在Model类中查看帮助程序link_to

时间:2011-01-17 13:18:57

标签: ruby-on-rails ruby-on-rails-3

使用Rails 3,有没有办法在模型中使用link_to helper或任何帮助器?

6 个答案:

答案 0 :(得分:80)

您可能需要在模型中使用link_to。是的,@ andy,这是对MVC的违反,但这并不意味着你应该得到积分而不回答这个问题。

@schwabsauce,比这更容易。如果你在初始化器或其他东西中执行它,那么第一行甚至不是必需的。同样适用于.sanitize和.raw以及其他很棒的其他功能。

ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionController::Base.helpers.link_to(whatever)

如果您想使用自动回路,可能必须在link_to中执行此操作:

Rails.application.routes.url_helpers.page_path(@page)

答案 1 :(得分:31)

如果您在Rails 3.2.1中执行此操作,请务必遵循Chuc​​k的帖子中提出的建议。看起来这种方法似乎不是一种安全的方法,可以在Rails 3.2.1中的非视图类中包含link_to帮助器。下面概述了一种更安全的方式(在任何情况下都适用于我们)。

当我们在其中一个课程中使用Chuck的帖子时,它最终会产生非常麻烦且难以调试的后果。它最终导致了副作用/错误,这些副作用/错误只出现在非常特殊(和罕见)的环境中。

据我们所知,问题在于这一行:

ActionView::Base.send(:include, Rails.application.routes.url_helpers)

告诉ActionView::Base要包含Rails.application.routes.url_helpersActionView::Base显然已经独自完成。让它第二次包含url_helpers,似乎会导致路由状态的重新初始化(包含ActionDispatch :: Routing :: UrlFor模块的类中的@_routes)。

这导致看似随意且无法解释的"未定义的方法' url_for'为零:NilClass"尝试直接或间接调用 ActionView::Base之后的url_for方法的视图中的异常第二次包含url_helpers

对我们有用的解决方案不是告诉ActionView::Base再次包含url_helpers,而是在您可能需要的地方自己包含UrlHelper模块。

然后,当您需要使用link_to并且可以访问路径时,您可以简单地执行此操作(假设login_path对您的应用程序有效):

include ActionView::Helpers::UrlHelper
...
link = link_to('here', Rails.application.routes.url_helpers.login_path)

我们花了很长时间和很多人为了追踪双包含引起的错误,我只是想在调整Rails基类的行为时警告别人要小心。

答案 2 :(得分:5)

我得到了以下内容:

include ActionView::Helpers::UrlHelper
include ActionController::UrlFor
include Rails.application.routes.url_helpers

cattr_accessor :controller
def controller; self.class.controller; end
def request; controller.request; end

然后在我的控制器中我填充了属性(从头创建一个控制器需要在参数哈希中有大量数据)。

Lead.controller = self

答案 3 :(得分:3)

link_to helper,MVC违规

安迪说,

如果你在模型中生成HTML,你可能需要仔细研究你正在做什么以及为什么。

网址助手

另一方面,

URL通常在视图控制器代码之外,在各种服务/表单/ api / ...类中派上用场,例如,甚至在模型中,如果必须的话。

是的,Rails.application.routes.url_helpers是一个模块,但这并不意味着你应该把它包含在任何地方或者像Gary所说的那样有趣的东西会开始发生:

https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all

你能做的是:

    delegate :url_helpers, :to => 'Rails.application.routes'

然后使用,例如

    url_helpers.home_url

答案 4 :(得分:0)

如果你想在任何地方使用任何模块的东西并且不介意违反所有的 Ruby 规范,把这个hackery 放到一个服务中:

module View
  extend self

  class HelperIncluder
    include ActionView::Helpers::UrlHelper
  end

  def link_to(*args)
    HelperIncluder.new.link_to(*args)
  end
end

现在:

View.link_to('a', 'b') => "<a href=\"b\">a</a>"

答案 5 :(得分:-7)

不是没有hackery。

如果您认为模型中需要link_to,则可能违反了Model-View-Controller architecture的某些原则。

模型应该是数据和业务逻辑的地方,但生成链接几乎肯定是控制器或视图的工作(或者,特别是Rails,在辅助类中)。