我们如何避免控制器中方法的重复/重复 - RAILS 3+

时间:2015-03-31 14:34:00

标签: ruby-on-rails ruby refactoring ruby-on-rails-4.2 ruby-2.2

我正在使用ruby on rails构建一个示例电子商务应用程序。我的控制器名称之一是" products_controller"。此控制器也作为嵌套控制器放置在内部。这些控制器内部的操作是相同的。如何在不重复代码的情况下代表这些行为。 代码示例如下。

应用程序/控制器/ products_controller.rb

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

应用程序/控制器/ master_admins / products_controller.rb

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

应用程序/控制器/ master_admins / properties_controller.rb

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

上面的操作包含相同的代码集。我们如何重构它以便代码不会重复。

提前致谢....

3 个答案:

答案 0 :(得分:3)

我建议使用concerns,这对DRY来说很棒。

对于控制器,可以在此处放置常用方法:

在我的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

然后,通过在控制器中包含common.rb来调用它

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

如果你有多个类使用这个类方法,你可以使用这样的东西(在common.rb中):

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

答案 1 :(得分:2)

您可以执行以下操作:

class GenericController < ActiveRecord::Base
  def index
    do something interesting
  end
end

class PropertiesController < GenericController
  # index is done
end

class ProductsController < GenericController
  # index is done
end

答案 2 :(得分:0)

您可以在控制器中使用before_action。它将在执行 index

之前执行 find_product
before_action :find_product, only: :index

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

def index
# some useful code
end

您可以删除&#34; only:&#34; 部分,以便在执行其他操作之前执行 find_product ,或将其移至 ApplicationController (或其他父控制器类)在所有相应的控制器中执行 before_action