假設我有一個名爲Thing的Rails模型。 Thing有一個url屬性,能夠選擇將其設置爲Internet上的某個URL。 在視圖代碼中,我須要執行如下操做的邏輯: app
<% if thing.url.blank? %> <%= link_to('Text', thing_path(thing)) %> <% else %> <%= link_to('Text', thing.url) %> <% end %>
視圖中的這種條件邏輯很難看。 固然,我能夠構建一個輔助函數,它會將視圖更改成: 函數
<%= thing_link('Text', thing) %>
這解決了冗長問題,但我真的更喜歡模型自己的功能。 在這種狀況下,視圖代碼將是: post
<%= link_to('Text', thing.link) %>
顯然,這須要模型上的連接方法。 這是它須要包含的內容: url
def link (self.url.blank?) ? thing_path(self) : self.url end
就問題而言,thing_path()是Model代碼中未定義的方法。 我假設能夠將一些輔助方法「拉入」模型中,可是如何? 是否有一個真正的緣由,路由只在控制器上運行並查看應用層? 我能夠想到許多模型代碼可能須要處理URL(與外部系統集成等)的狀況。 spa
任何與視圖中顯示的內容有關的邏輯都應該委託給輔助方法,由於模型中的方法嚴格用於處理數據。 code
這是你能夠作的: router
# 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) %>
雖然可能有一種方法我傾向於將這種邏輯排除在模型以外。 我贊成你不該該把它放在視圖中( 保持它很瘦 )但除非模型將一個url做爲一段數據返回給控制器,不然路由內容應該在控制器中。 ci
(編輯:忘記我之前的嘮叨......) 路由
好吧,可能會出現你要去模型或其餘網址的狀況......但我並不認爲這屬於模型,視圖(或模型)聽起來更合適。 get
關於路由,據我所知路由是控制器中的動做(一般「神奇地」使用視圖),而不是直接視圖。 控制器應處理全部請求,視圖應顯示結果,模型應處理數據並將其提供給視圖或控制器。 我據說不少人在談論到模型的路線(到目前爲止我已經開始接受它了),但據我所知:路線轉向控制器。 固然,許多控制器是一個模型的控制器,一般稱爲<modelname>sController
(例如「UsersController」是模型「User」的控制器)。
若是您發現本身在視圖中編寫了大量邏輯,請嘗試將邏輯移到更合適的位置; 請求和內部通訊邏輯可能屬於控制器,數據相關邏輯能夠放置在模型中(但不包括顯示邏輯,其包括連接標籤等),而且純粹顯示相關的邏輯將被放置在幫助器中。
我本身找到了關於如何作到這一點的答案。 在模型代碼中,只需:
對於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。
我真的很喜歡乾淨的解決方案。
class Router include Rails.application.routes.url_helpers def self.default_url_options ActionMailer::Base.default_url_options end end router = Router.new router.posts_url # http://localhost:3000/posts router.posts_path # /posts
它來自http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/