RoR: перенос кода из представления в помощник

Я пытаюсь лучше понять, как использовать помощники рельса вместе с представлениями haml.

У меня есть представление, которое изначально содержало эту логику

=   fund_levels_last(i, @fund_level_count) ? ( link_to "add new level", ad, {class: 'button orange sm'} ) : ( link_to "remove", accounts_ad_fund_level_path(ad, fl.object.id), {:class => 'button orange sm', :method => :delete, :remote => true, :confirm => t('q.are_you_sure')} )

Желая максимально очистить представление от кода, я пытался перенести эту логику в помощник.

   def fund_levels_last(i, flcount)
     if i ==  flcount
       true
     else
       false
     end
   end

   def fund_levels_btn(i, flcount)
     if self.fund_levels_last(i, flcount)
       link_to "add new level", ad, {class: 'button orange sm'}
     else
       link_to "remove", accounts_ad_fund_level_path(ad, fl.object.id), {:class => 'button orange sm', :method => :delete, :remote => true, :confirm => t('q.are_you_sure')}
     end
   end

Однако в помощнике у меня нет доступа к переменным и объектам в представлении (объявление, объект, фл и т. д.). Я полагаю, что мог бы передать все это вспомогательным методам, но почему-то это кажется слишком сложным, и у меня такое чувство, что я иду по ложному пути. Моя единственная строка кода в представлении кажется 15 строками кода в помощнике...

Каким будет самый простой способ перенести эту логику из представления в помощник?


person charliez    schedule 28.10.2012    source источник
comment
Вы можете взглянуть на github.com/drapergem/draper ,   -  person pjam    schedule 28.10.2012


Ответы (2)


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

<%= render :partial => 'funds/partial_view', :locals => { :var => variable } %>

но если вам нужен помощник, вам придется передать в качестве параметров:

def funds_helper(var) //do something interesting end

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

в контроллере: @fund_level = fund_levels_last(i, @fund_level_count)

в поле зрения: <%= @fund_level ? render :partial => 'funds/add_new_level' : render :partial => 'funds/remove_level' %>

Затем пусть ваши частичные представления будут правильными.

person Michael    schedule 28.10.2012
comment
Спасибо!! Решил сделать партиал, вызвав его с помощью render fund_level_form, f:f, ad:ad. Кажется, работает блестяще :) - person charliez; 29.10.2012

Кстати, метод

def fund_levels_last(i, flcount)
  if i ==  flcount
    true
  else
    false
  end
end

может быть просто:

def fund_levels_last(i, flcount)
  i ==  flcount
end

а также методы, которые возвращают логическое значение, часто заканчиваются на ?, поэтому оно становится def fund_levels_last?(i, flcount)

person pjam    schedule 28.10.2012
comment
Спасибо! Очевидно, что это гораздо более элегантный и эффективный код! Однако исходная проблема с перемещением логики представления в помощник остается. Я попытался сохранить link_to в представлении и просто вернуть данные link_to из помощника, но это тоже не сработало... - person charliez; 28.10.2012