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

上述动作包含相同的代码集。我们如何重构它以使代码不会重复。

提前致谢....

4

3 回答 3

5

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
于 2015-03-31T15:25:13.380 回答
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
于 2015-03-31T15:07:01.103 回答
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

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

于 2015-03-31T15:45:22.867 回答