能夠在模型中使用Rails路由助手(即mymodel_path(模型))嗎?

假設我有一個名爲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


#1樓

任何與視圖中顯示的內容有關的邏輯都應該委託給輔助方法,由於模型中的方法嚴格用於處理數據。 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) %>

#2樓

雖然可能有一種方法我傾向於將這種邏輯排除在模型以外。 我贊成你不該該把它放在視圖中( 保持它很瘦 )但除非模型將一個url做爲一段數據返回給控制器,不然路由內容應該在控制器中。 ci


#3樓

(編輯:忘記我之前的嘮叨......) 路由

好吧,可能會出現你要去模型或其餘網址的狀況......但我並不認爲這屬於模型,視圖(或模型)聽起來更合適。 get

關於路由,據我所知路由是控制器中的動做(一般「神奇地」使用視圖),而不是直接視圖。 控制器應處理全部請求,視圖應顯示結果,模型應處理數據並將其提供給視圖或控制器。 我據說不少人在談論到模型的路線(到目前爲止我已經開始接受它了),但據我所知:路線轉向控制器。 固然,許多控制器是一個模型的控制器,一般稱爲<modelname>sController (例如「UsersController」是模型「User」的控制器)。

若是您發現本身在視圖中編寫了大量邏輯,請嘗試將邏輯移到更合適的位置; 請求和內部通訊邏輯可能屬於控制器,數據相關邏輯能夠放置在模型中(但不包括顯示邏輯,其包括連接標籤等),而且純粹顯示相關的邏輯將被放置在幫助器中。


#4樓

我本身找到了關於如何作到這一點的答案。 在模型代碼中,只需:

對於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。


#5樓

我真的很喜歡乾淨的解決方案。

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/

相關文章
相關標籤/搜索