Substituting before_filter :load_object
Here’s a Rails controller pattern I’m using more often lately: Instead of loading an object with a before_filter
you can use a more intelligent helper_method
to get the main object for the controller context. It already sounds more complicated than it is, so here’s an example:
Before
class ProductController < ApplicationController
before_filter :load_product, :only => [:show, :edit, :update, :destroy]
# your standard CRUD methods here…
private
def load_product
@product = Product.find(params[:id])
end
end
This is pretty straight forward and I assume everyone has done that already, here’s a imho nicer approach…
After
class ProductController < ApplicationController
helper_method :product
…
def create
respond_to do |format|
if product.save
format.html { redirect_to product }
else
format.html { render :action => "new" }
end
end
end
def update
respond_to do |format|
if product.update_attributes(params[:product])
format.html { redirect_to product }
else
format.html { render :action => "edit" }
end
end
end
def destroy
product.destroy
respond_to do |format|
format.html { redirect_to products_url }
end
end
private
def product
@product ||= params[:id] ? Product.find(params[:id]) : Product.new(params[:product])
end
end
And beacause it is a helper method you can use it in your views just like that, for example in conjunction with a form:
%h1 New product
- form_for product do |f|
…
Of course you can adjust the helper method to fit your needs, maybe you need it to provide a nested object:
class ProductController < ApplicationController
helper_method :category, :product
def index
@products = catalog.products
end
# you get the idea…
private
def catalog
@catalog ||= params[:catalog_id] ? Catalog.find(params[:catalog_id]) : Catalog.new(params[:catalog])
end
def product
@product ||= params[:id] ? catalog.products.find(params[:id]) : catalog.products.build(params[:product])
end
end