首页 文章

可以在模型中使用Rails路由助手(即mymodel_path(模型))吗?

提问于
浏览
331

假设我有一个名为Thing的Rails模型 . Thing有一个url属性,可以在Internet上的某个地方设置为URL . 在视图代码中,我需要执行以下操作的逻辑:

<% if thing.url.blank? %>
<%= link_to('Text', thing_path(thing)) %>
<% else %>
<%= link_to('Text', thing.url) %>
<% end %>

视图中的这种条件逻辑很难看 . 当然,我可以构建一个辅助函数,它会将视图更改为:

<%= thing_link('Text', thing) %>

这解决了冗长问题,但我真的更喜欢模型本身的功能 . 在这种情况下,视图代码将是:

<%= link_to('Text', thing.link) %>

显然,这需要模型上的链接方法 . 这是它需要包含的内容:

def link
  (self.url.blank?) ? thing_path(self) : self.url
end

就问题而言,thing_path()是Model代码中未定义的方法 . 我假设可以将一些辅助方法“拉入”模型中,但是如何?是否有一个真正的原因,路由只在控制器上运行并查看应用程序层?我可以想到许多模型代码可能需要处理URL(与外部系统集成等)的情况 .

6 回答

  • 13

    (编辑:忘记我以前的唠叨......)

    好吧,可能会出现你要去模型或其他网址的情况......但我并不认为这属于模型,视图(或者模型)听起来更合适 .

    关于路由,据我所知路由是控制器中的动作(通常"magically"使用视图),而不是直接视图 . 控制器应处理所有请求,视图应显示结果,模型应处理数据并将其提供给视图或控制器 . 我've heard a lot of people here talking about routes to models (to the point I'米开始接受它了),但据我所知:路线进入控制器 . 当然,很多控制器都是一个模型的控制器,通常称为 <modelname>sController (例如"UsersController"是模型"User"的控制器) .

    如果您发现自己在视图中编写了大量逻辑,请尝试将逻辑移到更合适的位置;请求和内部通信逻辑可能属于控制器,数据相关逻辑可以放置在模型中(但不包括显示逻辑,其包括链接标签等),并且纯粹显示相关的逻辑将被放置在帮助器中 .

  • -1

    您可能还会发现以下方法比包含每种方法更清晰:

    class Thing
      delegate :url_helpers, to: 'Rails.application.routes' 
    
      def url
        url_helpers.thing_path(self)
      end
    end
    
  • 1

    任何与视图中显示的内容有关的逻辑都应该委托给辅助方法,因为模型中的方法严格用于处理数据 .

    这是你可以做的:

    # In the helper...
    
    def link_to_thing(text, thing)
      (thing.url?) ? link_to(text, thing_path(thing)) : link_to(text, thing.url)
    end
    
    # In the view...
    
    <%= link_to_thing("text", @thing) %>
    
  • 174

    虽然可能有一种方法我倾向于将这种逻辑排除在模型之外 . 我同意你不应该把它放在视图中(keep it skinny),但除非模型将url作为一段数据返回给控制器,否则路由内容应该在控制器中 .

  • 634

    在Rails 3,4和5中,您可以使用:

    Rails.application.routes.url_helpers
    

    例如

    Rails.application.routes.url_helpers.posts_path
    Rails.application.routes.url_helpers.posts_url(:host => "example.com")
    
  • 109

    我自己找到了关于如何做到这一点的答案 . 在模型代码中,只需:

    对于Rails <= 2:

    include ActionController::UrlWriter
    

    对于Rails 3:

    include Rails.application.routes.url_helpers
    

    这神奇地使 thing_path(self) 返回当前事物的URL,或 other_model_path(self.association_to_other_model) 返回其他一些URL .

相关问题