1

Я пытаюсь построить полиморфные отношения из вложенной формы, которая обратна ко всем найденным мной примерам. Я надеюсь, что кто-то укажет на ошибку моих путей.Rails 3 Полиморфные вложенные атрибуты

class Container < ActiveRecord::Base 
     belongs_to :content, :polymorphic => true 
end 
class Notice < ActiveRecord::Base 
     has_one :container, :as => :content 
end 
class Form < ActiveRecord::Base 
     has_one :container, :as => :content 
end 

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

Я думал, что я мог бы решить, добавив accepts_nested_attributes_for :content, но это дает мне unrecognized attribute :notice, когда я пытаюсь создать контейнер с вложенным Уведомлении (если смотреть на содержание, а не полиморфные ассоциации)

Я могу сделать это вручную, так и в явном виде исключить вложенные поля, такие как

if params[:container].has_key('notice') 
    @c = Container.new(params[:container].except(:notice)) 

а затем построить, но разве это не запах? Есть ли способ лучше?

Благодарим за понимание!

ответ

0

Вложенные атрибуты предназначены для работы от родителя до детей, а не наоборот. Более того, в этом случае, как вложенные атрибуты узнают, пытаетесь ли вы создать объект Notice или Form?

Если вы нашли его сушилку для создания содержимого из контейнера, вы, вероятно, ваши ассоциации наизнанку - попробуйте изменить схему для:

class Container < ActiveRecord::Base 
    has_one :notice 
    has_one :form 
end 

class Notice < ActiveRecord::Base 
    belongs_to :container 
end 

class Form < ActiveRecord::Base 
    belongs_to :container 
end 

Вы можете использовать проверку, чтобы гарантировать только одного ребенка (:notice или :form) на самом деле ассоциируется в случае необходимости.

+0

Хм. Я думал, что он будет знать, какой объект создать так же, как я, с помощью ключа simple_fields_for. Если я упоминаю has_one, я теряю способность делать Container.find (1) .content.get_data, где get_data определена в Уведомлении и Форме. – Questor

+0

Тогда вы можете изменить это, чтобы использовать STI и унаследовать уведомления и формы от абстрактного класса Content. Кроме того, вы можете создать вспомогательный метод и/или кеш в модели Container для поиска содержимого. – PinnyM

+0

+1 для abstract_class. Я пошел с STI, но посмотрю в .abstract_class = true, чтобы удалить дублированные поля. Благодаря! – Questor

Смежные вопросы