Rails - должен ли текст ссылки быть установлен в контроллере или представлении? - PullRequest
1 голос
/ 02 мая 2020

Я борюсь за то, сколько логики c должно быть в контроллере и сколько в представлении?

Например, у меня есть ссылка 'toggle', которая включает и выключает фильтр. Результатом является ссылка с некоторым текстом в зависимости от состояния переключателя и от того, добавлен ли параметр запроса или нет.

, т.е. в одном состоянии

<%= link_to 'With filter', polymorphic_path(Thing, { filtered: 1 }) %>

и в другом состоянии

<%= link_to 'Without filter', polymorphic_path(Thing, {}) %>

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

<%= link_to @filter_link_text, polymorphic_path(Thing, @filter_link_params) %>

но похоже, что я помещаю слишком много логик c вида в контроллер

или контроллер устанавливает простой флаг и оставляет остальное для просмотра. ..

<% if @offer_filter %>
  <%= link_to 'With filter', polymorphic_path(Thing, { filtered: 1 }) %>
<% else %>
  <%= link_to 'Without filter', polymorphic_path(Thing, {}) %>
<% end %>

Могут ли помочь переводы?

Спасибо.

1 Ответ

2 голосов
/ 02 мая 2020

У вас есть несколько вариантов, это зависит от обстоятельств.

Вы не хотите поместить текст просмотра в контроллер. Нет @filter_link_text. Контроллер соединяет модели с видами. Представление управляет тем, как все отображается.

Самое простое - это то, что вы уже предложили, контроллер устанавливает флаг, который использует представление.

<% if @offer_filter %>
  <%= link_to 'With filter', polymorphic_path(@thing, { filtered: 1 }) %>
<% else %>
  <%= link_to 'Without filter', polymorphic_path(@thing, {}) %>
<% end %>

Затем вы можете переместить это в парциальное . Переместите код в app/views/shared/_filtered_thing.html.erb и отобразите его в своем представлении. Это упрощает ваше представление и позволяет совместно использовать код представления.

<%= render 'shared/filtered_thing' %>

Средним шагом является использование декоратора . Декоратор - это тонкая обертка вокруг модели, которая позволяет добавлять и изменять ее поведение, определяя c для определенного использования. Это позволяет избежать насыщения модели множеством представлений.

draper реализует декораторы и хорошо связывается с Rails. Он использует очень похожую проблему в качестве примера.

class ThingDecorator < Draper::Decorator
  delegate_all

  def filter_toggle_link(filtered)
    if filtered
      # h allows access to the Rails helper methods
      h.link_to 'With filter', h.polymorphic_path(self, { filtered: 1 })
    else
      h.link_to 'Without filter', h.polymorphic_path(self, {})
    end
  end
end

Теперь ваше представление вызывает этот метод для декорированного объекта.

<%= @thing.filter_toggle_link(@offer_filter) %>

Вы также можете добавить флаги в ваш декоратор. Например, если вам нужно установить фильтр для каждого объекта.

class ThingDecorator < Draper::Decorator
  delegate_all

  attr_accessor :filtered

  def filter_toggle_link
    if filtered?
      # h allows access to the Rails helper methods
      h.link_to 'With filter', h.polymorphic_path(self, { filtered: 1 })
    else
      h.link_to 'Without filter', h.polymorphic_path(self, {})
    end
  end

  def filtered?
    filtered
  end
end

# In the controller
@thing.filtered = true

# In the view
<%= @thing.filter_toggle_link %>

Большое преимущество декоратора перед частичным представлением состоит в том, что вы можете модульно протестировать декоратор.

Открываются партиалы и декораторы больше способов сохранить ваши логики вида c хорошо продуманными и не допустить вздутие ваших контроллеров и моделей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...