1

我正在与控制器中应该有多少逻辑以及视图中应该有多少逻辑作斗争?

例如,我有一个“切换”链接,可以打开和关闭过滤器。结果是带有一些文本的链接,具体取决于切换的状态以及是否添加了查询参数。

即在一种状态

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

在另一个状态

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

我在控制器中分配链接标签和查询参数之间犹豫不决,所以我将在视图中没有逻辑,并且两个变量都设置在控制器中......

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

但似乎我在控制器中放入了太多视图逻辑

或者控制器设置一个简单的标志并将其余部分留给视图......

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

翻译有帮助吗?

谢谢。

4

1 回答 1

2

你有很多选择,这取决于具体情况。

不想将视图文本放入控制器中。没有@filter_link_text。控制器将模型连接到视图。视图处理事物的显示方式。

最简单的是您已经建议的,控制器设置视图使用的标志。

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

然后你可以把它移到一个partial中。将代码移入app/views/shared/_filtered_thing.html.erb并在您的视图中呈现。这简化了您的视图并允许共享视图代码。

<%= render 'shared/filtered_thing' %>

中间立场是使用装饰器。装饰器是模型周围的薄包装器,可让您添加和更改其特定于特定用途的行为。它避免了用一堆视图代码使模型变胖。

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 %>

与局部视图相比,装饰器的一大优势是您可以对装饰器进行单元测试。

Partials 和 decorators 开辟了更多的方法来保持你的视图逻辑很好地分解并防止它膨胀你的控制器和模型。

于 2020-05-02T08:22:14.893 回答