Thing이라는 Rails 모델이 있다고 가정 해 봅시다. 사물은 인터넷 어딘가에 URL로 선택적 으로 설정할 수있는 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 ()는 모델 코드 내에서 정의되지 않은 메소드입니다. 일부 도우미 메서드를 모델에 “풀인”할 수 있다고 가정하지만 어떻게? 라우팅이 컨트롤러에서만 작동하고 앱의 레이어를 보는 실제적인 이유가 있습니까? 모델 코드가 URL을 처리해야하는 경우 (외부 시스템과의 통합 등)를 생각할 수 있습니다.
답변
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")
답변
이 작업을 수행하는 방법에 대한 답변을 찾았습니다. 모델 코드 안에 다음을 입력하십시오.
레일 <= 2 :
include ActionController::UrlWriter
레일 3의 경우 :
include Rails.application.routes.url_helpers
마술처럼 thing_path(self)
현재의 URL을 other_model_path(self.association_to_other_model)
반환 하거나 다른 URL을 반환합니다.
답변
모든 방법을 포함하는 것보다 다음과 같은 접근 방식이 더 깨끗할 수도 있습니다.
class Thing
delegate :url_helpers, to: 'Rails.application.routes'
def url
url_helpers.thing_path(self)
end
end
답변
모델의 메소드는 데이터를 처리하기위한 것이므로 뷰에 표시된 것과 관련된 모든 로직은 헬퍼 메소드에 위임되어야합니다.
할 수있는 일은 다음과 같습니다.
# 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) %>
답변
나는 깨끗한 해결책을 따르는 것을 정말로 좋아합니다.
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/ 에서 온 것입니다 .
답변
방법이있을 수 있지만 모델에서 그런 종류의 논리를 유지하는 경향이 있습니다. 나는 당신이 그것을 뷰에 넣지 말아야한다는 것에 동의 하지만 ( 스키니 유지 ) 모델이 URL을 컨트롤러에 데이터 조각으로 반환하지 않는 한 라우팅 항목은 컨트롤러에 있어야합니다.
답변
(편집 : 이전 babble을 잊어 버려라 …)
좋아, 모델이나 다른 URL로 갈 수있는 상황이있을 수 있습니다 …하지만 이것이 모델에 속한다고 생각하지는 않습니다.보기 (또는 모델)가 더 적절하게 들립니다.
내가 아는 한 경로에 대해서는 경로가 직접 컨트롤러가 아닌 컨트롤러의 작업 (일반적으로 “매직”보기)을 사용하는 것입니다. 컨트롤러는 모든 요청을 처리하고, 뷰는 결과를 제시해야하며, 모델은 데이터를 처리하고이를 뷰 또는 컨트롤러에 제공해야합니다. 여기서 많은 사람들이 모델로가는 길 (내가 가장 믿기 시작한 시점까지)에 대해 이야기하는 것을 들었습니다. 그러나 제가 이해하는대로 : 길은 컨트롤러로갑니다. 물론 많은 컨트롤러가 한 모델의 컨트롤러이며 종종 호출됩니다 <modelname>sController
(예 : “UsersController”는 “User”모델의 컨트롤러입니다).
보기에서 불쾌한 양의 논리를 작성하는 경우 논리를보다 적절한 위치로 이동하십시오. 요청 및 내부 통신 로직은 아마도 컨트롤러에 속할 수 있으며, 데이터 관련 로직은 모델에 배치 될 수 있지만 (링크 태그 등을 포함하는 디스플레이 로직은 아님) 순수한 디스플레이 관련 로직은 헬퍼에 배치됩니다.