我正在使用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
上面的操作包含相同的代码集。我们如何重构它以便代码不会重复。
提前致谢....
答案 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_productbefore_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 。