2015-09-23 2 views
-2

я использую Rails 4.2 и я хочу, чтобы реорганизовать мой вспомогательный метод, чтобы избавиться от дублирования кода:Rails: рефакторинг кода с блоками

В приложение/хелперов/администратор/tasks_helper.rb

def chosen_select(name, method, chzes, selected = nil, options = {}, html_options = {}) 
    options[:value_method] ||= :id 
    options[:text_method] ||= :name 
    if options.key?(:placeholder) 
    html_options['data-placeholder'.intern] = options[:placeholder] 
    options.delete(:placeholder) 
    end 
    if html_options.key?(:class) 
    html_options[:class] = 'chosen-select ' + html_options[:class] 
    else 
    html_options[:class] = 'chosen-select' 
    end 
    chzes = options_from_collection_for_select(chzes, options[:value_method], options[:text_method], selected) 
    options.delete(:value_method) 
    options.delete(:text_method) 
    select(name, method, chzes, options.merge!(include_hidden: false), html_options) 
end 

def chosen_select_array(name, method, chzes, selected = nil, options = {}, html_options = {}) 
    options[:value_method] ||= :id 
    options[:text_method] ||= :name 
    if options.key?(:placeholder) 
    html_options['data-placeholder'.intern] = options[:placeholder] 
    options.delete(:placeholder) 
    end 
    if html_options.key?(:class) 
    html_options[:class] = 'chosen-select ' + html_options[:class] 
    else 
    html_options[:class] = 'chosen-select' 
    end 
    chzes = options_for_select(chzes, selected) 
    options.delete(:value_method) 
    options.delete(:text_method) 
    select(name, method, chzes, options.merge!(include_hidden: false), html_options) 
end 

I мой взгляд у меня есть много вызовов метода, как приложение/просмотров/администратора/задачи/index.html.erb

<%= chosen_select(:select, :project_id, [TaskFilterOptgroups.active_projects, TaskFilterOptgroups.inactive_projects] , @task_filter_configuration.project_id, {:include_blank => true, :placeholder => 'Project'}, {'data-last-project_id' => @task_filter_configuration.project_id, :style => 'width: 150px;'}) %> 

так, что я не хочу, чтобы изменить мой метод вызывает в представлении. Моя попытка сделать универсальный метод «chosen_select_generic», который будет вызываться из конкретного метода, как «chosen_select»:

def chosen_select_generic(name, method, chzes, selected = nil, options = {}, html_options = {}) 
    options[:value_method] ||= :id 
    options[:text_method] ||= :name 
    if options.key?(:placeholder) 
    html_options['data-placeholder'.intern] = options[:placeholder] 
    options.delete(:placeholder) 
    end 
    if html_options.key?(:class) 
    html_options[:class] = 'chosen-select ' + html_options[:class] 
    else 
    html_options[:class] = 'chosen-select' 
    end 
    # 2 different chzes in 2 methods: 
    # 1) chosen_select(...) 
    # chzes = options_from_collection_for_select(chzes, options[:value_method], options[:text_method], selected) 
    # 2) chosen_select_array(...) 
    # chzes = options_for_select(chzes, selected)  
    yield chzes 
    options.delete(:value_method) 
    options.delete(:text_method) 
    select(name, method, chzes, options.merge!(include_hidden: false), html_options) 
end 

, а затем chosen_select может выглядеть следующим образом:

def chosen_select(name, method, chzes, selected = nil, options = {}, html_options = {}) 
    chosen_select_generic(name, method, chzes, selected = nil, options = {}, html_options = {}) do |contents| 
    chzes = option_groups_from_collection_for_select(chzes, :entries, :status, options[:value_method], options[:text_method], selected) 
    end 
end 

Но это Безразлично» т работы. Как я могу извлечь дубликат кода в блоке без изменения вызовов метода в представлении?

+0

В 'chosen_select_array', вы обеспечиваете значение 'options [: value_method]' и 'options [: text_method]', а затем удаляет их, не используя их. Зачем это? – sawa

+0

@SergioTulentsev Это в 'options_for_select (chzes, selected)'? – sawa

+0

@SergioTulentsev Где это? – sawa

ответ

1

Это задание в вашем блоке не будет делать то, что вы думаете:

chzes = option_groups_from_collection_for_select(...) 

Это создает новую локальную переменную вместо изменения внешний. Если это изменяемая только часть здесь, то вы можете просто вернуть его из блока:

chosen_select_generic(name, method, chzes, selected = nil, options = {}, html_options = {}) do |chzes| 
    option_groups_from_collection_for_select(chzes, :entries, :status, options[:value_method], options[:text_method], selected) 
end 

И получить значение в вашем универсальном методе, как это:

chzes = yield(chzes) 
+0

Привет, Серджио, большое вам спасибо за вашу помощь. – StandardNerd

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