rails 3 has_many: ошибка сохранения записи - PullRequest
6 голосов
/ 14 октября 2010

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

У меня есть has_many :through, а в модели соединения есть поля, которые не являются внешними ключами. Когда я собираю модели и пытаюсь сохранить их, я получаю ошибку проверки полей не внешнего ключа из модели соединения.

Мои файлы выглядят так:

Person.rb

  has_many :wedding_assignments, :dependent => :destroy
  has_many :weddings, :through=>:wedding_assignments
  accepts_nested_attributes_for :weddings
  accepts_nested_attributes_for :wedding_assignments

Wedding.rb

  has_many :wedding_assignments, :dependent => :destroy
  has_many :people, :through=>:wedding_assignments
  accepts_nested_attributes_for :people
  accepts_nested_attributes_for :wedding_assignments

WeddingAssignment.rb

  belongs_to :person
  belongs_to :wedding
  validates_presence_of :role, :person, :wedding

(роль - строка)

people_controller.rb

  def new
    @person = Person.new

    1.times do
      wedding = @person.weddings.build
      1.times do
        assignment = wedding.wedding_assignments.build
        assignment.person = @person
        assignment.wedding = wedding
      end
    end
  end

  def create
    @person = Person.new(params[:person])
    @person.weddings.each do |wedding|
      wedding.wedding_assignments.each do |assignment|
        assignment.person = @person  #i don't think I should need to set person and wedding manually, but I get a validation error if I don't
        assignment.wedding = wedding
      end
    end
 end

возвращаемые параметры выглядят так:

{"first_name"=>"", "last_name"=>"", "weddings_attributes"=>{"0"=>{"wedding_assignments_attributes"=>{"0"=>{"role"=>"Bride's Maid", "budget"=>""}}, "date"=>"", "ceremony_notes"=>""}}}

И точная ошибка:

ActiveRecord::RecordInvalid in PeopleController#create
Validation failed: Role can't be blank

Что явно не правильно, так как вы можете увидеть это в params[]

Что я делаю не так?

Это рельсы 3.0.0

Ответы [ 2 ]

1 голос
/ 19 октября 2010

Правильно, это немного догадка, поэтому извиняюсь, если я закончу тратить ваше время здесь ...

Мне кажется, что в вашем методе создания вы создаете «свадьбу»отношения (которые на самом деле являются только «притворными» отношениями, они используют: through =>: wedding_assignments), а затем возвращают это.Затем вы просите рельсы воссоздать эти объекты при вызове Person.new.Я предполагаю, что rails запутывается, пытаясь создать объект на противоположной стороне has_many: без присутствия промежуточного объекта.

Я бы немного соблазнился реструктурировать это (непроверенный код!):

def new
  @person = Person.new
  @wedding = Wedding.new
  @wedding_assignment = WeddingAssignment.new
end

def create
  @person = Person.new(params[:person])
  @wedding = Wedding.new(params[:person])
  @assignment = WeddingAssignment.new(params[:wedding_assignment].merge({:person => @person}))
end

У меня такое чувство, что это будет работать до последней строки.Я подозреваю, чтобы это работало, вам может понадобиться использовать транзакции:

def create
  @person = Person.new(params[:person])
  @wedding = Wedding.new(params[:person])
  ActiveRecord::Base.transaction do
    if @person.valid? && @wedding.valid?
      [@person,@wedding].each.save!
      @assignment = WeddingAssignment.new(params[:wedding_assignment].merge({:person => @person}))
      @assignment.save!
    end
  end
end

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

Надеюсь, это поможет, и не станет тупиком.

0 голосов
/ 19 октября 2010

Попробуйте изменить «Person.new» на «Person.create», возможно, создание записи в БД сразу же поможет с ассоциациями.

...