Я должен был сделать нечто подобное в моем приложении. Я взял то, что придумал, и немного изменил, но я не проверял, так что будьте осторожны. Это не красиво, но лучше, чем все остальное, что я мог придумать.
В маршрутах .rb:
resources :posts, :pictures
controller :comments do
get '*path/edit' => :edit, :as => :edit_comment
get '*path' => :show, :as => :comment
# etc. The order of these is important. If #show came first, it would direct /edit to #show and simply tack on '/edit' to the path param.
end
В комментариях.рб:
embedded_in :commentable, :inverse_of => :comments
def to_param
[commentable.class.to_s.downcase.pluralize, commentable.id, 'comments', id].join '/'
end
В фильтре before в comments_controller.rb:
parent_type, parent_id, scrap, id = params[:path].split '/'
# Security: Make sure people can't just pass in whatever models they feel like
raise "Uh-oh!" unless %w(posts pictures).include? parent_type
@parent = parent_type.singularize.capitalize.constantize.find(parent_id)
@comment = @parent.comments.find(id)
Хорошо, уродство прошло. Теперь вы можете добавлять комментарии к любым моделям и просто делать:
edit_comment_path @comment
url_for @comment
redirect_to @comment
и т. Д.
Редактировать: я не реализовывал никаких других путей в своем собственном приложении, потому что все, что мне было нужно, это редактировать и обновлять, но я думаю, что они будут выглядеть примерно так:
controller :comments do
get '*path/edit' => :edit, :as => :edit_comment
get '*path' => :show, :as => :comment
put '*path' => :update
delete '*path' => :destroy
end
Другие действия будут хитрее. Вам, вероятно, нужно сделать что-то вроде:
get ':parent_type/:parent_id/comments' => :index, :as => :comments
post ':parent_type/:parent_id/comments' => :create
get ':parent_type/:parent_id/comments/new' => :new, :as => :new_comment
Затем вы получите доступ к родительской модели в контроллере, используя params [: parent_type] и params [: parent_id]. Вам также необходимо передать правильные параметры помощникам URL:
comments_path('pictures', 7)