在单个Rails资源上组合浅层和非浅层路由

时间:2011-07-30 04:27:46

标签: ruby-on-rails ruby-on-rails-3 routing nested-resources

假设我有Magazine模型和Ad模型,Magazine :has_many => :ads。我已按如下方式设置嵌套资源路由:

resources :magazines do 
  resources :ads, :shallow => true do
    get 'search', :action => :search, :on => :collection
  end
end

我的目标是能够在嵌套和浅层访问由Rails资源创建的默认CRUD路由以及搜索路由。我希望用户能够在给定杂志的上下文中限制他的搜索,或者搜索所有广告而不管父杂志,因为某些广告不会有父杂志。 换句话说,我希望能够:

/magazines/1/ads/new
/ads/new

/magazines/1/ads/search
/ads/search

# ... all standard CRUD routes ...

我担心视图中的路径变量依赖于new_magazine_ad_path(@magazine)之类的东西。在没有任何/ads/index实例指导的情况下,访问new_magazine_ad_path(@magazine)帮助程序时,是否会访问@magazine之类的路由(其中应包含创建新广告的链接)中断?


P.S .: 通常情况下,我会自己尝试这一切,看看哪些方法有效,但我现在仍然坚持上述设置 - 我只能进行编辑,删除,显示和更新浅路线:

/ads/:id
/ads/:id/edit
/ads/:id (put)
/ads/:id (delete)

并且没有新的或索引路线:

/ads/index
/ads/new

更新

所以Shreyas建议创建两个控制器,一个用于处理嵌套广告,另一个用于处理浅层广告。这是有道理的,但它让我复制所有视图代码只是为了将路径助手从magazine_ad_path(@magazine)更改为ad_path关于处理视图的DRY方法的任何想法都会改变吗?所有其他视图代码都是相同的。

2 个答案:

答案 0 :(得分:2)

  

我希望用户能够限制他的搜索范围   给定杂志的上下文,或搜索所有广告而不管父母   杂志,因为有些广告不会有母版杂志

这里有两个不同的问题。我建议你有两个不同的控制器来解决这两个问题。当然其中一个是杂志背景下的,另一个是独立的控制器(一个没有父母杂志的AD)。

通过这种方式,您可以使用两个不同的控制器

resources :ads do
  get 'search', :action => :search, :on => :collection
end
resources :magazines do 
  resources :ads, :shallow => true do
    get 'search', :action => :search, :on => :collection
  end
end

答案 1 :(得分:0)

您可以使用url_for的一次调用来生成任一路线(通过polymorphic_url)。

url_for [:search, @magazine, :ads]
# when @magazine is present, this is equivalent to search_magazine_ads_url
# when @magazine is nil, it's search_ads_url

url_for [:new, @magazine, :ad] #=> new_magazine_ad_url or new_ad_url
url_for [@magazine, :ads] #=> magazine_ads_url or ads_url

您甚至可以将数组传递给link_to来代替命名助手生成的路由。

link_to 'New Ad', [:new, @magazine, :ad]

http://apidock.com/rails/ActionDispatch/Routing/PolymorphicRoutes