Mani kandan Mani kandan - 7 months ago 14
Ruby Question

How can we avoid duplication/repeatition of methods in controllers - RAILS 3+

I am building a sample e-commerce app using ruby on rails.One of my controller name is "products_controller".This controller is also placed inside as a nested controller.The actions inside these controllers are same.How can we represent these actions without duplication of codes.
The code samples are given below.

app/controllers/products_controller.rb

def index
@product = Product.all
@vari = @products.variants
.............
.............
end


app/controllers/master_admins/products_controller.rb

def index
@product = Product.all
@vari = @products.variants
.............
.............
end


app/controllers/master_admins/properties_controller.rb

def product
@product = Product.all
@vari = @products.variants
.............
.............
end


The above actions contains the same set of codes.How can we refactor this so that the code doesnt get repeated.

Thanks in advance....

Answer

I would suggest using concerns which are awesome for DRY.

For the controller, common methods can be placed here:

In my app/controllers/concerns/common.rb

module Common
  extend ActiveSupport::Concern

  module ClassMethods
    ## This is a Class method, call it just like you call any other class method
    def get_products_and_variants
      @product = Self.all
      @vari = @product.variants
    end
  end

## Instance method, if you don't want aclass method, use this instance method
def my_instance_method
  ## code for method
end

Then, call it by including common.rb in the controller*

include Common

def index
  ## This will make @product and @vari available
  Product.get_products_and_variants

  # ............
end



## Other method using same method call
def product
  ## This will make @product and @vari available
  Product.get_products_and_variants

  # .............
end

If you have multiple classes using this class method, you can use something like this (in common.rb):

def get_details        
  if self == Product
     ## Get products
  elsif self == Variant
     ## Get variants
  elsif self == ProductDetail
     ## Get product details
  end              
end