View helpers are useful files that contain reusable code in an attempt to keep your views DRY and clean. They can be found in the /app/helpers directory. You can simply add methods here that you intend to reuse in your views.
Let's say you want to method to format a date object a specific way all the time (January 1, 2019). You could create a method here called mint_date(date) and place your logic inside. This method then can be used anywhere in any view.
In /app/helpers/application_helper.rb:
module ApplicationHelper
def mint_date(date)
date.strftime('%B %e, %Y')
end
endIn /app/views/months/show.html.erb:
Summary for <%= mint_date(@report.start_date) %>
So you might've noticed that we always probably want our transactions to be order by date and not by ID. There is a simple way to ensure that our records always get returned by date by adding a model scope to our transaction model. https://guides.rubyonrails.org/active_record_querying.html#scopes
in /app/models/transaction.rb add:
scope :by_date, -> { order(date: :desc) }this is literally the same as writing
def self.by_date
order(date: :desc)
endJust a bit more concise
Now in /app/controllers/transactions_controller.rb you can replace @transactions = Transaction.order(date: :desc).all with @transactions = Transaction.by_date.all.
We've used when implementing out clearance authentication in our /app/controllers/backend_controller.rb
before_action :require_login
Take a look at /app/controllers/transactions_controller.rb and notice how many times we are doing Transaction.find(params[:id]) we can make this much more DRY by using helper_method https://api.rubyonrails.org/classes/AbstractController/Helpers/ClassMethods.html#method-i-helper_method
In the private area of our controller let's add:
def transaction
@transaction ||= Transaction.find(params[:id])
endThis method says to set the variable @transaction to be Transaction.find(params[:id]) ONLY if it's not already set whenever transaction is called. This means it gives us the ability to explicitly set @transaction if we need to.
Next add as the first line in your controller class:
helper_method :transactionNow the method transaction will now be available in your view
You can update your actions to remove @transactions wherever necessary like in show, edit, update, destroy. And explicitly set it for new and create.
class TransactionsController < BackendController
helper_method :transaction
def index
@transactions = Transaction.order(date: :desc).all
end
def show; end
def new
@transaction = Transaction.new
end
def create
@transaction = Transaction.new(transaction_params)
if @transaction.save
redirect_to transaction_path(@transaction)
else
render :new
end
end
def edit; end
def update
if transaction.update(transaction_params)
redirect_to transaction_path(@transaction)
else
render :edit
end
end
def destroy
transaction.destroy
redirect_to transactions_path
end
private
def transaction
@transaction ||= Transaction.find(params[:id])
end
def transaction_params
params.require(:transaction).permit(:name, :amount, :date, :transaction_type, :notes, :category_id)
end
endNext we should replace @transaction (calls the variable) with transaction (calls your new method, which returns the variable) in the transaction views