Ответ 1
У вас есть два маршрута, которые указывают на posts#show
(вы должны подтвердить это, запустив rake routes
), и ваша ссылка использует неправильный.
Когда вы вызываете link_to('show', post)
, URL-адрес ссылки генерируется вызовом url_for(post)
, который (в конце концов, после прохождения нескольких других способов на пути) вызывает post_path(post)
. Поскольку маршрут до posts#show
, созданный вашим вызовом resources(:posts)
, называется post
, это маршрут, который генерирует post_path
.
В настоящее время у вас также есть непоследовательные маршруты для показа, обновления и уничтожения действий, которые, вероятно, вызывают проблемы позже.
Вы можете исправить это, изменив маршруты на следующее:
resources :posts, :except => ['show', 'update', 'destroy']
get 'posts/:id/:slug' => 'posts#show', :as => 'post'
put 'posts/:id/:slug' => 'posts#update'
delete 'posts/:id/:slug' => 'posts#destroy'
К сожалению, пока вы еще не можете использовать link_to('show', post)
, потому что он полагается на возможность использовать post.to_param
в качестве единственного аргумента, необходимого для создания пути к сообщению. Для вашего настраиваемого маршрута требуются два аргумента: id
и a slug
. Итак, теперь ваш код ссылки должен выглядеть так:
link_to 'show', post_path(post.id, post.slug)
Вы можете обойти эту проблему, указав свои собственные post_path
и post_url
помощники в app/helpers/posts_helper.rb
:
module PostsHelper
def post_path(post, options={})
post_url(post, options.merge(:only_path => true))
end
def post_url(post, options={})
url_for(options.merge(:controller => 'posts', :action => 'show',
:id => post.id, :slug => post.slug))
end
end
Это означает, что мы, наконец, можем использовать:
link_to 'show', post
Если все это похоже на слишком много работы, обычной альтернативой является использование URL-адресов, которые больше похожи на posts/:id-:slug
, и в этом случае вы можете придерживаться стандартных маршрутов RESTful и просто переопределять метод to_param
в своем post
> класс:
def to_param
"#{id}-#{slug}"
end
Вам также нужно немного поработать с разделением params[:id]
на идентификатор и пул, прежде чем вы сможете найти соответствующий экземпляр в вашем шоу, отредактировать, обновить и уничтожить действия контроллера.