Почему моя модель запускает проверку не в то время?

В моем edit действие моего employees_controller У меня есть эта строка кода:

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses << Address.new
71: end

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

Существует полиморфная ассоциация как это: Person <- User <- Employee и Person имеет many-many отношения с Address. То объявление похоже на это:

#class Person
has_many :address_person_links, :dependent => :destroy
has_many :addresses,
  :through => :address_person_links,
  :uniq => true,
  :validate => false, # I thought this would fix it but doesn't
  :dependent => :destroy

Код приводит к сбою на строке 70 из employees_controller.rb:

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1090:in `save_without_dirty!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:87:in `save_without_transactions!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/has_many_through_association.rb:63:in `insert_record'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:119:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:433:in `add_record_to_target_with_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:118:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:116:in `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:116:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:141:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:140:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:115:in `<<'
/home/aaron/NetBeansProjects/onlinescheduler/app/controllers/employees_controller.rb:70:in `edit'

Заметьте как его вызов save? Почему это делает это?

1
задан aarona 9 May 2010 в 04:37
поделиться

2 ответа

Это происходит потому, что всякий раз, когда вы добавляете объект AR в массив ассоциаций, он сохраняет объект и пытается добавить его id в таблицу ассоциаций (если это many_to_many)

Вы можете попробовать следующее

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses = [Address.new]
71: end

Также, если вы делаете это с accepts_nested_attributes_for, по правилам нужно использовать build метод

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses.build
71: end

Смотрите http://ryandaigle. com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes for more information

1
ответ дан 3 September 2019 в 00:43
поделиться

Во-первых, могу я предложить вам проверить следующее, для смысловой ясности:

if @employee.user.person.addresses.empty?

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

Вы можете изменить свои проверки адреса, чтобы избежать их выполнения, если это только что созданная запись (например, когда вы только что добавили ее к человеку с помощью "<<". Например, так:

validates_presence_of :name, :unless => Proc.new{|a|a.new_record?}

Вам придется добавить блок :unless к каждой из ваших валидаций адреса.

1
ответ дан 3 September 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: