如何在Ruby on Rails中使用Application Helpers

Chr*_*art 20 ruby-on-rails

我试图在网站的每个页面上发布一个随机的推荐.

我开始使用这样的应用程序助手:

module ApplicationHelper

  def random_testimonial
    @random_testimonial = Testimonial.find(:first, :offset => rand(Testimonial.count))
  end

end
Run Code Online (Sandbox Code Playgroud)

在我看来,我可以引用该方法,但它在每个引用上被调用,这是有道理的.

我希望在每个页面视图上调用一次,以显示我可以在视图中使用的推荐对象.

我该怎么做才能做到这一点?

Sco*_*ler 50

虽然这有效,而且我当然知道这样做,但它违反了MVC的关注点分离.视图助手不应包含控制器/模型类型逻辑,这样做.

您可以考虑将其重构为应用程序控制器.辅助器应该用于视图格式化和东西,而不是作为一个函数(这是我开始时一直想做的事情.)

如果你回到你的Testimonail模型,那就可以做到

def self.random
  Testimonial.find(:first, :offset => rand(Testimonial.count))
end
Run Code Online (Sandbox Code Playgroud)

然后在您的应用程序控制器中,您可以:

def random_testimonial
  @random_testimonial ||= Testimonial.random
end
Run Code Online (Sandbox Code Playgroud)

并从before_filter调用它

这具有将数据库逻辑移回其所属的模型的优点.

  • 同意.投票你的解决方案,斯科特.克里斯,我建议你选择斯科特的答案作为正确答案.我太专注于缓存变量的问题而忽略了设计中的这个明显缺陷. (5认同)
  • 我知道这真的很老,但这不正确.MVC中的View可以查询模型,它只是无法对其进行操作.因此,View Helpers可以独立于控制器查询模型状态. (2认同)

Mil*_*ota 6

如果我理解正确,您需要一个方法,每次在一个请求/响应周期中引用它时返回相同的对象.如果这是真的,你可以通过对你的助手进行一些小改动来实现它:

 def random_testimonial
    @random_testimonial ||= Testimonial.find(:first, :offset => rand(Testimonial.count))
 end
Run Code Online (Sandbox Code Playgroud)

注意"|| ="部分.这是一个Ruby习语,它说:为@random_testimonial赋值,除非它已经有值.

希望这能回答你的问题.