Rails - краткий поиск родительского ресурса для полиморфно вложенного ресурса - PullRequest
5 голосов
/ 29 января 2010

Предположим, у меня такая полиморфная структура.

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_filter :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

Это довольно уродливо. Всякий раз, когда мы добавляем новую вещь, к которой она может принадлежать, нам нужно добавить ее неСУХОЙ к этому before_filter.

Становится еще хуже. Предположим, что Foos - это действительно полиморфные вещи, которые могут появляться где угодно, например, комментарии или теги. И предположим, что у вас есть следующие маршруты:

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

... теперь нам нужно беспокоиться о том, нужно ли сначала проверять bar_id или baz_id.

Для более сложных ресурсов, возможно, этого будет недостаточно, чтобы быть уверенным, что вы получите идентификатор родителя.

Что было бы идеально, если бы мы могли сделать что-то вроде этого:

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

В конце концов, наши маршруты уже кодируют родительский элемент в соответствии с порядком параметров в URL. Зачем отбрасывать эту информацию?

Итак: как это можно сделать?

1 Ответ

4 голосов
/ 29 января 2010

Вы должны иметь возможность попросить foo.parent

Вам понадобится что-то вроде этого:

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