1

Я создаю пример приложения электронной коммерции, используя ruby ​​on rails. Одно из моего имени контроллера - «product_controller». Этот контроллер также размещен внутри как вложенные контроллеры. Действия внутри этих контроллеров одинаковы. Как мы можем представить эти действия без дублирования кодов. Образцы кода приведены ниже.Как избежать дублирования/повторения методов в контроллерах - RAILS 3+

приложение/контроллеры/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 

Вышеуказанные действия содержат один и тот же набор кодов. Как мы можем реорганизовать это так t код не будет повторяться.

Заранее спасибо ....

+1

Я думаю, что лучший вопрос - почему вам нужны несколько контроллеров с одним и тем же кодом? Если вы беспокоитесь о контроле доступа, почему бы не обработать это с помощью ролей? – mmichael

+0

я также использую этот набор кодов в вложенных контроллерах. Это действие индекса контроллера продукта происходит в следующих URL-адресах моего проекта. «localhost: 3000/products», «localhost: 3000/master_admins/products», «localhost: 3000/property_admins/products». –

ответ

3

Я предложил бы использовать concerns, которые являются удивительным для DRY.

Для контроллера, общие методы могут быть размещены здесь:

В моем приложение/контроллеры/проблем/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 
+0

Могу ли я использовать что-то вроде этого ..... product = Product.all product_category = ProductCategory.all product_sub_category = ProductSubCategory.all properties = product_sub_category.properties –

+0

yes @ Manikandan ,, для нескольких классов с использованием одного класса метода в common.rb ,, я предлагаю использовать if elseif способ кодирования (например, метод get_details), чтобы вы могли проверить который класс вызывает, например, self == Product, и может идти вперед. Вы также можете использовать загрузку с использованием: – Milind

+0

Спасибо за помощь @Milind ... Это помогло мне решить мою проблему ...... еще раз спасибо за тратя ваше драгоценное время на это .... :) –

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 
0

Вы можете использовать before_action в контроллере. Он будет выполнять find_product перед выполнением индекса:

before_action :find_product, only: :index 

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

def index 
# some useful code 
end 

Вы можете удалить «только:» части для выполнения find_product перед другими действиями, или переместить его в ApplicationController (или другой родитель класс контроллера) для выполнения before_action во всех соответствующих контроллерах.

 Смежные вопросы

  • Нет связанных вопросов^_^