Skip to content

Commit

Permalink
add transaction
Browse files Browse the repository at this point in the history
* added category relation
* added shoulda-matchers gem
* added TargetRubyVersion to rubocop config
  • Loading branch information
agilous committed Dec 31, 2023
1 parent 2ef4cb4 commit 6ea2042
Show file tree
Hide file tree
Showing 26 changed files with 521 additions and 1 deletion.
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ AllCops:
- node_modules/**/*
- lib/tasks/*
NewCops: enable
TargetRubyVersion: 3.2.2

Rails/I18nLocaleTexts:
Enabled: false
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ group :test do
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
gem 'shoulda-matchers'
gem 'webdrivers'
end
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ GEM
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
shoulda-matchers (6.0.0)
activesupport (>= 5.2.0)
sprockets (4.2.1)
concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4)
Expand Down Expand Up @@ -331,6 +333,7 @@ DEPENDENCIES
rubocop-performance
rubocop-rails
rubocop-rspec
shoulda-matchers
sprockets-rails
stimulus-rails
turbo-rails
Expand Down
71 changes: 71 additions & 0 deletions app/controllers/transactions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

class TransactionsController < ApplicationController
before_action :set_transaction, only: %i[show edit update destroy]

# GET /transactions or /transactions.json
def index
@transactions = Transaction.all
end

# GET /transactions/1 or /transactions/1.json
def show; end

# GET /transactions/new
def new
@transaction = Transaction.new
end

# GET /transactions/1/edit
def edit; end

# POST /transactions or /transactions.json
def create
@transaction = Transaction.new(transaction_params)

respond_to do |format|
if @transaction.save
format.html { redirect_to transaction_url(@transaction), notice: 'Transaction was successfully created.' }
format.json { render :show, status: :created, location: @transaction }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @transaction.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /transactions/1 or /transactions/1.json
def update
respond_to do |format|
if @transaction.update(transaction_params)
format.html { redirect_to transaction_url(@transaction), notice: 'Transaction was successfully updated.' }
format.json { render :show, status: :ok, location: @transaction }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @transaction.errors, status: :unprocessable_entity }
end
end
end

# DELETE /transactions/1 or /transactions/1.json
def destroy
@transaction.destroy!

respond_to do |format|
format.html { redirect_to transactions_url, notice: 'Transaction was successfully destroyed.' }
format.json { head :no_content }
end
end

private

# Use callbacks to share common setup or constraints between actions.
def set_transaction
@transaction = Transaction.find(params[:id])
end

# Only allow a list of trusted parameters through.
def transaction_params
params.require(:transaction).permit(:date, :amount, :description, :category_id)
end
end
4 changes: 4 additions & 0 deletions app/helpers/transactions_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

module TransactionsHelper
end
2 changes: 2 additions & 0 deletions app/models/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

class Category < ApplicationRecord
validates :name, uniqueness: true, presence: true

has_many :transactions, dependent: :nullify
end
9 changes: 9 additions & 0 deletions app/models/transaction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class Transaction < ApplicationRecord
validates :amount, presence: true
validates :date, presence: true
validates :description, presence: true

belongs_to :category, optional: true
end
37 changes: 37 additions & 0 deletions app/views/transactions/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<%= form_with(model: transaction) do |form| %>
<% if transaction.errors.any? %>
<div style="color: red">
<h2><%= pluralize(transaction.errors.count, "error") %> prohibited this transaction from being saved:</h2>

<ul>
<% transaction.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :date, style: "display: block" %>
<%= form.date_field :date %>
</div>

<div>
<%= form.label :amount, style: "display: block" %>
<%= form.number_field :amount %>
</div>

<div>
<%= form.label :description, style: "display: block" %>
<%= form.text_field :description %>
</div>

<div>
<%= form.label :category_id, style: "display: block" %>
<%= form.text_field :category_id %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
22 changes: 22 additions & 0 deletions app/views/transactions/_transaction.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div id="<%= dom_id transaction %>">
<p>
<strong>Date:</strong>
<%= transaction.date %>
</p>

<p>
<strong>Amount:</strong>
<%= transaction.amount %>
</p>

<p>
<strong>Description:</strong>
<%= transaction.description %>
</p>

<p>
<strong>Category:</strong>
<%= transaction.category_id %>
</p>

</div>
4 changes: 4 additions & 0 deletions app/views/transactions/_transaction.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.extract! transaction, :id, :date, :amount, :description, :category_id, :created_at, :updated_at
json.url transaction_url(transaction, format: :json)
10 changes: 10 additions & 0 deletions app/views/transactions/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Editing transaction</h1>

<%= render "form", transaction: @transaction %>

<br>

<div>
<%= link_to "Show this transaction", @transaction %> |
<%= link_to "Back to transactions", transactions_path %>
</div>
14 changes: 14 additions & 0 deletions app/views/transactions/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<h1>Transactions</h1>

<div id="transactions">
<% @transactions.each do |transaction| %>
<%= render transaction %>
<p>
<%= link_to "Show this transaction", transaction %>
</p>
<% end %>
</div>

<%= link_to "New transaction", new_transaction_path %>
3 changes: 3 additions & 0 deletions app/views/transactions/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.array! @transactions, partial: 'transactions/transaction', as: :transaction
9 changes: 9 additions & 0 deletions app/views/transactions/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>New transaction</h1>

<%= render "form", transaction: @transaction %>

<br>

<div>
<%= link_to "Back to transactions", transactions_path %>
</div>
10 changes: 10 additions & 0 deletions app/views/transactions/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @transaction %>

<div>
<%= link_to "Edit this transaction", edit_transaction_path(@transaction) %> |
<%= link_to "Back to transactions", transactions_path %>

<%= button_to "Destroy this transaction", @transaction, method: :delete %>
</div>
3 changes: 3 additions & 0 deletions app/views/transactions/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.partial! 'transactions/transaction', transaction: @transaction
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Rails.application.routes.draw do
resources :transactions
resources :categories
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

Expand Down
12 changes: 12 additions & 0 deletions db/migrate/20231230212509_create_transactions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateTransactions < ActiveRecord::Migration[7.2]
def change
create_table :transactions do |t|
t.date :date, null: false
t.integer :amount, null: false
t.string :description, null: false
t.references :category, foreign_key: true, null: true

t.timestamps
end
end
end
13 changes: 12 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions spec/factories/transaction_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

FactoryBot.define do
factory :transaction do
date { Time.zone.today }
amount { rand(100..1000) }
sequence(:description) { |i| "description-#{i}" }
end
end
97 changes: 97 additions & 0 deletions spec/features/transaction_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

require 'rails_helper'

describe 'Transaction' do
describe 'creating' do
before do
visit new_transaction_path

fill_in 'Amount', with: '1000'
fill_in 'Date', with: '2005-02-13'
fill_in 'Description', with: 'Shell'

click_button 'Create Transaction'
end

it 'displays a success message' do
expect(page).to have_text 'Transaction was successfully created.'
end

it 'displays the new Transaction' do
expect(page).to have_text "Date: 2005-02-13\nAmount: 1000\nDescription: Shell"
end
end

describe 'deleting' do
let(:transaction) { create(:transaction) }

before do
visit transaction_path(transaction)

click_button 'Destroy this transaction'
end

it 'displays a success message' do
expect(page).to have_text 'Transaction was successfully destroyed.'
end

it 'returns to the index view' do
expect(page).to have_current_path(transactions_path)
end
end

describe 'indexing' do
let!(:transactions) { create_list(:transaction, 3) }

before do
visit transactions_path
end

it 'lists all the transaction names' do
expect(transactions).to(be_all do |t|
!page.text(/Date: #{t.date}\nAmount: #{t.amount}Description: #{t.description}/).nil?
end)
end
end

describe 'showing' do
let(:transaction) { create(:transaction) }

before do
visit transaction_path(transaction)
end

it 'displays the transaction amount' do
expect(page).to have_text "Amount: #{transaction.amount}"
end

it 'displays the transaction date' do
expect(page).to have_text "Date: #{transaction.date}"
end

it 'displays the transaction description' do
expect(page).to have_text "Description: #{transaction.description}"
end
end

describe 'updating' do
let(:transaction) { create(:transaction) }
let(:new_amount) { transaction.amount + 100 }

before do
visit edit_transaction_path(transaction)

fill_in 'Amount', with: new_amount
click_button 'Update Transaction'
end

it 'displays a success message' do
expect(page).to have_text 'Transaction was successfully updated.'
end

it 'displays the updated Transaction' do
expect(page).to have_text "Amount: #{new_amount}"
end
end
end
Loading

0 comments on commit 6ea2042

Please sign in to comment.