私は自分のアプリで似たようなことをしなければなりませんでした。思いついたものを少し変更しましたが、テストしていないので、注意して使用してください。きれいではありませんが、私が考えた何よりも優れています。
routes.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
comment.rb で:
embedded_in :commentable, :inverse_of => :comments
def to_param
[commentable.class.to_s.downcase.pluralize, commentable.id, 'comments', id].join '/'
end
comments_controller.rb の before フィルター:
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)