开发者

Rails - Succinctly finding the parent resource of a polymorphically nested resource

开发者 https://www.devze.com 2022-12-18 05:48 出处:网络
Suppose I have a polymorphic structure like this. map.resources :bar, :has_many => :foo map.resources :baz, :has_many => :foo

Suppose I have a polymorphic structure like this.

map.resources :bar, :has_many => :foo
map.resources :baz, :has_many => :foo
map.resources :qux, :has_many => :foo

class Foo
  belongs_to :parent, :polymorphic => true
end

class FooController < AC
 before_filte开发者_如何转开发r :find_parent

 ...

 private
 def find_parent
  # ugly way:
  @parent = if params[:bar_id]
   Bar.find(params[:bar_id])
  elsif params[:baz_id]
   Baz.find(params[:baz_id])
  elsif params[:qux_id]
   Qux.find(params[:qux_id])
  end 
 end
end

That's pretty ugly. Whenever we add a new thing that it might belong to, we need to add it un-DRYly to that before_filter.

It gets worse, too. Suppose that Foos are really polymorphic things that could show up anywhere, like comments or tags. And suppose that you have the following routes:

map.resources :bar, :has_many => :foo do |bar|
 bar.resources :baz, :has_many => :foo
end
map.resources :qux, :has_many => :foo do |qux|
 qux.resources :baz, :has_many => :foo
end

... now we have to worry about whether to check for bar_id or baz_id first.

For more complex resources, it's possible that this won't even be enough to be sure you get the parent's id.

What would be ideal is if we could do something like this:

def get_parent
 # fetch the parameter that immediately preceeded :id
 @parent = if x = params.before(:id)
   # polymorphic find
   x.key.to_s[0..-4].classify.constantize.find x.value
 end
end

After all, our routes already encode the parent by virtue of the order of parameters in the URL. Why discard that information?

So: how can this be done?


You should be able to ask for foo.parent

You'll need to have something like this:

class Bar < ActiveRecord::Base
  has_many :foos, :as => :parent
  ...
end
0

精彩评论

暂无评论...
验证码 换一张
取 消