Rails:重构,观点,帮助者:这一切是如何结合在一起的?

San*_*ago 16 refactoring views ruby-on-rails helper

警告:Noob在这里.

我知道这是一个微不足道的主题,但是我很难弄清楚如何通过将他们的部分内容转化为帮助来简化我的观点.例如,我一直认为你的视图中的条件是提取助手的主要候选者,但我无法找到这样的例子,而我实现这一目标的尝试失败了.

例如,假设我有:

#index.html.erb

<% for beast in @beasts do -%>
  <% if beast.dead? -%>
    <%= beast.body %>
    <%= link_to "bury", bury_beast_path( :id => beast.id ) %>
  <% else -%>
    <%= beast.body %>
    <%= link_to "kill!", kill_beast_path( :id => beast.id ) %>
  <% end -%>
<% end -%>
Run Code Online (Sandbox Code Playgroud)

在我看来,这让我有点恼火,但我怎么能把它转移到助手呢?如果可能的话,进一步简化它.(我已经读到某个条件很糟糕的地方,但是如果没有它们,你可以编程任何东西.)

又如:我需要idbody的格式标记controller_action.到目前为止我得到的最好的是:

#index.html.erb

<body id="<%= controller_action %>">
Run Code Online (Sandbox Code Playgroud)

…和…

#application_helper.rb

def controller_action
  @id = @controller.controller_name + "_" + @controller.action_name
end
Run Code Online (Sandbox Code Playgroud)

我不是专家,但即使对我来说,这仍然是丑陋的.

为了使事情变得更复杂,Ryan Singer说了一些我喜欢的事情:将ERB视为图像标签,使用帮助器"揭示意图".然后在下一次呼吸说你应该没有助手的HTML,这是地狱的方式.WTF?两者如何兼容?如果它可以在视图中声明行为,那么肯定应该在幕后呈现大量的HTML吗?我无法掌握它.

所以,基本上就是这样.我很感激,如果有人可以分享一些关于这方面的想法,或者指出我对这个主题有一些深入的阅读 - 我发现它在网络上的覆盖范围非常薄弱.我已经用谷歌搜索到了疲惫,但谁知道呢.

EmF*_*mFi 26

重构使您的视图更易于维护.问题是选择重构代码的去向.

你的两个选择是局部帮助.没有石头规则规定应该在哪里使用.有一些指南浮出水面,就像一个指出帮助者不应该包含HTML.

通常,partials更适合重构比ruby更多HTML/ERB/HAML的部分.另一方面,助手用于最少HTML的ruby代码块或从参数生成简单的HTML.

但是,我不同意帮助者根本不应包含HTML的观点.有点可以,只是不要过度.处理帮助程序的方式阻碍了它们用于生成大量HTML.这就是为什么建议您的助手包含最少量的HTML.如果你看看源代码附带的帮助程序,你会注意到它们中的大多数生成了html.少数没有,主要用于生成参数和评估常见条件.

例如,任何表单助手或link_to变体都适合第一种形式的助手.虽然像url_for和logged_in这样的东西?由各种认证模型提供的是第二种.

这是我用来确定是否将代码从视图分解为部分或帮助的决策链.

  1. 重复或几乎相同的语句产生一个浅的html标签?=>帮助者.
  2. 常用表达式用作另一个帮助器的参数?=>帮助者.
  3. 长表达式(超过4个术语)用作另一个助手的参数?=>帮助者.
  4. 4条或更多条红宝石(未评估为HTML)?=>帮助者.
  5. 几乎所有其他东西=>偏.

我将使用您要重构的代码作为示例:

我会以这种方式重构问题中的视图:

应用程序/佣工/ beast_helper.rb:

def beast_action(beast)
  if beast.dead?
    link_to "bury", bury_beast_path(beast)
  else
    link_to "kill!", kill_beast_path(beast)
  end
end
Run Code Online (Sandbox Code Playgroud)

应用程序/视图/兽/ _beast.html.erb:

<%= beast.body %>
<%= beast_action(beast) %>
Run Code Online (Sandbox Code Playgroud)

应用程序/视图/兽/ index.html.erb:

<%= render :partial => "beast", :collection => @beasts %>
Run Code Online (Sandbox Code Playgroud)

它在技术上更复杂,因为它是3个文件,总共10行而不是1个文件和10行.这些视图现在只有3行,分布在2个文件中.最终结果是您的代码更加干燥.允许您在其他控制器/操作/视图中重用部分或全部部分,而且复杂性最小.

至于你的身体标签id.你应该真的使用content_for/yield.对于那种事情.

应用程序/视图/布局/ application.html.erb

...
<body id="<%= yield(:body_id) %>">
...
Run Code Online (Sandbox Code Playgroud)

应用程序/视图/兽/ index.html.erb

<% content_for :body_id, controller_action %>
...
Run Code Online (Sandbox Code Playgroud)

这将允许您在任何需要它的视图中覆盖正文的id.例如:

应用程序/视图/用户/ preferences.html.erb

<% content_for :body_id, "my_preferences" %>
Run Code Online (Sandbox Code Playgroud)


jon*_*nii 8

我要做的第一件事就是:

#index.html.erb
<%= render @beasts %>

#_beast.html.erb
<%= beast.body %>
<%= link_to_next_beast_action(beast) %>    

#beast_helper.rb
def link_to_next_beast_action(beast)
  if beast.dead?
    link_to "bury", bury_beast_path( :id => beast.id ) 
  else
    link_to "kill!", kill_beast_path( :id => beast.id )
  end
end
Run Code Online (Sandbox Code Playgroud)

我所做的是将野兽的渲染分离成使用集合语义的部分.

然后我已经将用于显示杀戮/埋葬链接的逻辑移动到野兽助手中.这样,如果你决定添加另一个动作(例如,'从死里恢复'),你只需要改变你的助手.

这有帮助吗?

  • @EmFi我投了你的答案,因为你详细了解了何时使用偏/助手. (2认同)