在Model类中查看helper link_to

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

有一些原因可能需要在模型中使用link_to。 是的@andy,这是对MVC的违反,但这并不意味着你不应该回答这个问题。

@schwabsauce,比这更容易。 如果你在初始化程序或其他东西中执行,第一行甚至不是必须的。 同样的东西适用于.sanitize和.raw以及其他一些真棒函数。

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

如果你想使用autopaths,你可能需要在你的link_to里面这样做:

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

如果你在Rails 3.2.1中这样做的话,要非常小心地遵循Chuc​​k的post中提出的build议。 这看起来好像这种方法是不是一个安全的方式去包括在Rails 3.2.1的非视图类link_to助手。 下面列出了一个更安全的方法(对我们来说,无论如何)。

当我们在其中一个课程中使用Chuck的post的时候,结果很麻烦,很难debugging后果。 它最终导致副作用/错误,只有在非常特殊的(罕见的)情况下出现。

就我们所知,这个问题是这样的:

 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“for nil:NilClass”exception,这些exception直接或间接地 ActionView::Base第二次包含url_helpers 之后调用url_for方法。

为我们工作的解决scheme是,而不是告诉ActionView::Base再次包含url_helpers ,只要你自己包含UrlHelper模块,你可能需要它。

然后,当你需要使用link_to并且可以访问path时,你可以简单地这样做(假设login_path对你的应用有效):

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

我们花了很长的时间和相当多的头脑来追踪双重包含引起的错误,而我只是想提醒别人在调整Rails基类的行为的时候要小心。

我得到这个工作与以下内容:

 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 

然后在我的控制器中填充属性(从头开始创build一个控制器需要参数散列中的大量数据)。

 Lead.controller = self 

link_to帮手,MVC违规

安迪说,

如果您在模型中生成HTML,您可能需要长时间观察您正在做什么以及为什么。

url助手

另一方面,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 

不是没有hackery。

如果您认为在模型中需要link_to ,那么您可能违反了Model-View-Controller体系结构的一些原则。

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