Учитывая следующее определение ресурса:
map.resources :posts, :except => [:show]
map.post '/:year/:month/:slug, :controller => :posts, :action => :show
Я могу сделать url_for
работа для меня, с помощью этого синтаксиса:
<%= link_to @post.title, post_url(:year => '2010', :month => '02', :slug => 'test') %>
Но есть ли способ сделать эту работу?
<%= link_to @post.title, @post %>
В настоящее время это бросает эту ошибку:
No route matches {:year=>#<Post id: 1, title: "test", (...)>, :controller=>"posts", :action=>"show"}
По-видимому, это передает объект @post первому параметру маршрута (походит на ошибку направляющих...). Но я могу сделать эту работу для меня? Я добавлю то питание с default_url_options
тупик.
Решение, работающее только в направляющих 3.x, в порядке, но я предпочел бы не использовать любые плагины.
Как насчет исправления url_for
для PostsController
? Может быть, не очень элегантно, но он СУХОЙ, и все должно работать.
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
protected
def url_for(options = {} )
if options[:year].class.to_s == "Post"
obj = options[:year]
options[:year] = obj.year
options[:month] = obj.month
options[:slug] = obj.slug
end
super(options)
end
end
Переопределить to_param
. Значение по умолчанию для to_param
- это идентификатор записи, но вы можете его изменить.
class Post
def to_param
"/#{year}/#{month}/#{slug}"
end
end
(Предполагается, что у вас есть методы в классе Post
для года
, месяца
и slug
).
Теперь, когда URL-адреса сгенерированы, будет вызван ваш замещенный to_param
.
<%= link_to @post.title, @post %>
=> <a href="/2010/02/foobar">Foobar</a>
Очевидно, вы должны убедиться, что действие show PostsController может найти запись на основе переданных параметров.
Возможно, вам придется изменить определение маршрута и исключить этот маршрут:
map.post '/:year/:month/:slug, :controller => :posts, :action => :show
Однако, с переопределением to_param
, RESTful post_path
по умолчанию будет работать нормально для нужных URL-адресов. чтобы генерировать.
К сожалению, когда вы передаете ActiveRecord в link_to
, он пытается использовать помощники полиморфных URL-адресов для генерации URL-адреса для ссылки.
Помощники полиморфных URL-адресов предназначены только для создания URL-адресов RESTful с использованием идентификатора записи вашего ActiveRecord.
Поскольку ваш маршрут использует несколько атрибутов объекта Post, помощники Polymorphic URL не оснащены для генерации правильного URL ... не столько ошибка, сколько ограничение :)
Углубление в link_to
, когда вы передаете ему хэш, он не использует полиморфную маршрутизацию, поэтому вы избегаете всей проблемы.
Я полагаю, что хакерским подходом было бы определение метода в Post под названием routing_hash
, который возвращает
(:year => post.year, :month => post.month, :slug => post.slug)
Я понимаю, что это не СУХОЙ подход, но это лучшее, что я могу придумать на данный момент