Automatically add parent model id in nested resources

▼魔方 西西 提交于 2019-12-04 13:40:51

Shallow Routing seems to be what you're looking for. You can implement shallow nesting as below :

resources :magazines do
  shallow do
    resources :ads
  end
end

OR

resources :magazines, :shallow => true do
  resources :ads
end

Only the index and the new actions are nested.

Using nested resources tends to generate long URLs, shallow nesting helps remove parts (that contain the parent resource route as well) that aren't necessarily required for certain actions(since a parent resource can be derived from a persisted child record).

One possible but ugly solution is:

module RoutesHelper
  def ad_path(ad)
    magazine_ad_path(ad.magazine, ad)
  end

  def ad_url(ad)
    magazine_ad_url(ad.magazine, ad)
  end

  def edit_ad_path(ad)
    edit_magazine_ad_path(ad.magazine, ad)
  end

  def edit_ad_url(ad)
    edit_magazine_ad_url(ad.magazine, ad)
  end

  ...
end

[ActionView::Base, ActionController::Base].each do |m|
  m.module_eval { include RoutesHelper }
end

Unfortunately, this has the disadvantage that I have to define different helpers for _path and _url because redirect_to uses the _url helpers, I have to write the edit_ helpers manually (and maybe I'm missing some; not sure on that), and it's just plain ugly.

One solution i like to use in this case is to make the instance returning his own path, like this:

class Ad
  def path action=nil
    [action, magazine, self]
  end
end

Then in your view you can use this array as a polymorphic route:

link_to @ad.path
link_to @ad.path(:edit)

Of course it also work with redirect_to, etc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!