2016-09-11 3 views
0

В моем приложении Rails я использую odf-report gem для создания отчетов. Однако у меня есть if condition в моем методе с теми же 110 строками кода в каждом разделе с одним или двумя изменениями в конце. Мне интересно, есть ли способ определить 110 строк, которые повторяются в блоке кода, и просто вызвать этот блок кода в моем основном методе? Ниже приведен пример способа:Кодовый блок Rails в контроллере для повторного кода

def print_enrolment_form_completed 
    kid = Kid.find(params[:id]) 
    if kid.not_anaphylactic? 
    report = ODFReport::Report.new("#{Rails.root}/app/reports/Student_Enrolment_Completed.odt") do |r| 
     #same 110 lines of code 
    end 
    else 
    report = ODFReport::Report.new("#{Rails.root}/app/reports/Student_Enrolment_Completed_Allergy.odt") do |r| 
     #same 110 lines of code 
     r.add_field(:a2, kid.fish ? "Yes" : "No") 
     r.add_field(:a3, kid.eggs ? "Yes" : "No") 
     r.add_field(:a4, kid.milk ? "Yes" : "No") 
    end 
    end 
end 

Моя цель состоит в том, чтобы просто дать кодовый блок, где комментарий указан выше, и имеет 110 линий, определенные в другом месте в контроллере. Любые идеи приветствуются!

+1

Не можете ли вы установить, какой отчет вы используете с if. А затем переместите 110 строк за пределы if? Просто убедитесь, что отчет находится в области действия, выполнив report = nil вне if. – Doon

+2

ваш оператор if не имеет смысла - в обоих ветвях вы создаете тот же отчет –

+0

Вы можете извлечь код в Proc и выполнить код в двух отдельных контекстах с использованием метода 'instance_eval' – illusionist

ответ

0

Определенно согласен, что многие строки кода в контроллере являются запахами кода, а не только отсутствием СУХОЙ.

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

report = ODFReport::Report.new(kid.not_anaphylactic? ? "#{Rails.root}/app/reports/Student_Enrolment_Completed.odt" : "#{Rails.root}/app/reports/Student_Enrolment_Completed_Allergy.odt") do |r| 
    #same 110 lines of code 
    If kid.not_anaphylactic? 
     r.add_field(:a2, kid.fish ? "Yes" : "No") 
     r.add_field(:a3, kid.eggs ? "Yes" : "No") 
     r.add_field(:a4, kid.milk ? "Yes" : "No") 
    end 
end 
0

Не можете ли вы просто создать метод, содержащий 110 строк кода и использовать его в инструкции if?

def method_name(z, y) 
     puts z + y 
    end 

    x = 4 

    if x > 3 
     method_name(6, 7) 
    else 
     method_name(1, 4) 
    end 
1

Вы ошибаетесь, если у вас есть 1000 строк в действии контроллера. Я думаю, что вам следует рассмотреть отложенные задания/активные задания или sidekiq или resque