У меня есть две модели, связанные таблицей соединений:
class Publication < ActiveRecord::Base
attr_accessible :title, :author_attributes, :translator_attributes
has_many :publication_contributors
has_many :authors, :through => :publication_contributors, :source => :contributor,
:conditions => {:publication_contributors => {:contributor_type => "Author"}}
has_many :translators, :through => :publication_contributors, :source => :contributor,
:conditions => {:publication_contributors => {:contributor_type => "Translator"}}
accepts_nested_attributes_for :authors, :translators
end
class Contributor < ActiveRecord::Base
attr_accessible :name
has_many :publications, :through => :publication_contributors
has_many :publication_contributors
end
class PublicationContributor < ActiveRecord::Base
attr_accessible :contributor_type
belongs_to :publication
belongs_to :contributor
end
Обратите внимание, что у таблицы соединения есть третий атрибут (помимо публикации_id и вкладчика_идентификатора), который называется вкладчик_тип. Этот атрибут может содержать такую роль, как «Автор», «Переводчик», «Редактор» или что-то еще. В моей модели публикации я создал пару ассоциаций для двух наиболее распространенных типов участников: «Автор» и «Переводчик». Эти ассоциации хорошо работают при извлечении соответствующих данных, например, с помощью @publication.authors
. Однако при создании этих ассоциаций через вложенную форму он тормозит.
Моя форма выглядит примерно так:
<%= form_for @publication, :remote => true do |f| %>
<%= f.label :title %>:
<%= f.text_field :title %>
<%= f.fields_for :authors do |builder| %>
<%= builder.label :name, "Author" %>:
<%= builder.text_field :name %>
<% end %>
<%= f.fields_for :translators do |builder| %>
<%= builder.label :name, "Translator" %>:
<%= builder.text_field :name %>
<% end %>
<%= f.submit %>
<% end %>
В моем контроллере:
def create
publication = Publication.create(params[:publication])
end
Форма отображается, как и ожидалось, но во время действия создания она зависает. Я надеялся, что Rails узнает, как волшебным образом назначить правильный contributor_type на основе условий в ассоциациях Publication, таких как:
has_many :authors, :through => :publication_contributors, :source => :contributor,
:conditions => {:publication_contributors => {:contributor_type => "Author"}}
К сожалению, это не так. Я получаю эту ошибку во время создания:
Mysql2::Error: Column 'contributor_type' cannot be null
Это заставляет меня думать, что мой единственный выход — вручную назначить contributor_type в обратном вызове before_create
, но если это так, как мне определить, какой тип назначить? Параметры имеют правильный тип в своем имени, например:
publication[authors_attributes][0][name]
Есть ли способ получить доступ к этой информации на уровне модели?
ОБНОВИТЬ:
Мое new
действие:
def new
@publication = Publication.new
publication_contributor = @publication.publication_contributors.build
contributor = publication_contributor.contributor.build
end
Он выдает эту ошибку в последней строке (настройка contributor
):
undefined method `build' for nil:NilClass
contributor_type
находится в таблице соединений, а не в модели участников. Поскольку я на самом деле не объявляю таблицу соединения в форме, у меня нет доступа к ее атрибутам, даже со скрытым полем. Однако, возможно, если есть способ создать таблицу соединений в форме, этот подход может сработать. Я посмотрю на это. Дайте мне знать, если у вас есть другие предложения. - person nullnullnull   schedule 05.02.2013publication_contributor.contributor.new
. Это вызывает ошибкуundefined method 'new' for nil:NilClass
. Я получаю те же результаты с.build
. Интересно, не поддерживает ли ActiveRecord вложение от дочернего к родительскому? В документах эта ситуация не упоминается. так или другой. - person nullnullnull   schedule 05.02.2013