Ruby on rails 通过关联获取ActiveRecord::RecordInvalid错误与\u多个;联接表上的验证问题
我有三个类似的关联模型:Ruby on rails 通过关联获取ActiveRecord::RecordInvalid错误与\u多个;联接表上的验证问题,ruby-on-rails,ruby,ruby-on-rails-3,activerecord,has-many-through,Ruby On Rails,Ruby,Ruby On Rails 3,Activerecord,Has Many Through,我有三个类似的关联模型: class Product < ActiveRecord::Base belongs_to :user has_many :descriptions, { dependent: :destroy, before_add: [:add_user_id_to_description, :validate_description] } has_many :documents, through: :descriptions # ...
class Product < ActiveRecord::Base
belongs_to :user
has_many :descriptions, {
dependent: :destroy,
before_add: [:add_user_id_to_description, :validate_description]
}
has_many :documents, through: :descriptions
# ...
def validate_description(d)
unless d.valid?
d.errors[:user_id].each do |err|
self.errors.add(:base, "Doc error: #{err}")
end
end
end
end
class Document < ActiveRecord::Base
belongs_to :user
has_many :descriptions, {
dependent: :destroy,
before_add: [:add_user_id_to_description, :validate_description]
}
has_many :products, through: :descriptions
end
class Description < ActiveRecord::Base
belongs_to :user
belongs_to :product
belongs_to :document
end
而description
验证失败,然后我得到false
和doc
上的相应错误。这正是我想要的
但是,如果doc
已经存在,例如:
doc = user.documents.first
doc.update_attributes(:product_ids => [1,2])
而description
验证失败,则出现ActiveRecord::RecordInvalid
错误
我确切地知道为什么会发生这种情况——调用save中的insert\u record
方法代码>内部,这会传播错误。它会提前退出,跳过此调用以获取新记录
有什么方法可以设置我的模型来防止这种保存代码>?或者我是被迫从错误中解救出来的
编辑
我试过下面卡洛斯·德鲁描述的设置;我还尝试了设置验证\u关联的:描述
,并将反向的::whatever
添加到中有许多:描述
选项散列。我还尝试在产品
和文档
模型上设置验证前
回调,但显然关联回调首先运行(?)。每次尝试似乎都会产生完全相同的错误信息
我正在从下面的控制台粘贴错误跟踪
Document Load (1.8ms) SELECT "documents".* FROM "documents" WHERE "documents"."user_id" = 19 ORDER BY "documents"."id" DESC LIMIT 1
(1.0ms) BEGIN
Product Load (41.7ms) SELECT "products".* FROM "products" WHERE "products"."id" = $1 LIMIT 1 [["id", 3640]]
Product Load (4.1ms) SELECT "products".* FROM "products" INNER JOIN "descriptions" ON "products"."id" = "descriptions"."product_id" WHERE "descriptions"."document_id" = 3552
User Load (7.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 19 LIMIT 1
Account Load (2.0ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 19 LIMIT 1
(0.9ms) SELECT COUNT(*) FROM "descriptions" WHERE "descriptions"."user_id" = 19
(1.2ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: User You have reached limit of 1
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_methods/dirty.rb:33:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `block in save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/has_many_through_association.rb:85:in `save_through_record'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/has_many_through_association.rb:52:in `insert_record'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:496:in `block (2 levels) in concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:344:in `add_to_target'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:495:in `block in concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:493:in `each'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:493:in `concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:134:in `block in concat'
... 14 levels...
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/builder/collection_association.rb:71:in `block in define_writers'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `each'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/persistence.rb:216:in `block in update_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/persistence.rb:215:in `update_attributes'
from (irb):2
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Document Load(1.8ms)从“documents”中选择“documents”。*其中“documents”。“user_id”=19按“documents”排序。“id”描述限制1
(1.0毫秒)开始
产品负载(41.7ms)从“产品”中选择“产品”。*其中“产品”。“id”=1美元限额1[[“id”,3640]]
产品加载(4.1ms)选择“产品”。*从“产品”内部连接“产品”上的“说明”。“id”=“说明”。“产品id”中的“说明”。“文档id”=3552
用户加载(7.0ms)从“用户”中选择“用户”。*其中“用户”。“id”=19限制1
帐户加载(2.0ms)从“帐户”中选择“帐户”。*其中“帐户”。“用户id”=19限制1
(0.9ms)从“说明”中选择计数(*),其中“说明”。“用户id”=19
(1.2ms)回滚
ActiveRecord::RecordInvalid:验证失败:用户已达到1的限制
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in'save!'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/attribute\u methods/dirty.rb:33:in'save!'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:在“保存中的块”中
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/transactions.rb:313:in `块入,事务返回\u状态'
来自/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/connection\u adapters/abstract/database\u语句。rb:192:在“事务”中
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in“transaction”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/transactions.rb:311:in`with\u transaction\u returning\u status'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in'save!'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u-record/associations/has\u-many\u-through\u-association.rb:85:in'save\u-through\u-record'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/has\u many\u-to\u-association.rb:52:in'insert\u-record'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:496:concat\u records中的“块(2级)”中
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:344:“添加到目标”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:495:in“concat\u记录中的块”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:493:in'each'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:493:in'concat\u records'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/collection\u association.rb:134:in'block in concat'
... 14级。。。
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/associations/builder/collection\u association.rb:71:“定义中的块”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/attribute\u assignment.rb:85:在“分配属性中的块”中
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/attribute\u assignment.rb:78:in'each'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/attribute\u assignment.rb:78:in“assign\u attributes”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/persistence.rb:216:“更新中的块属性”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/transactions.rb:313:in `块入,事务返回\u状态'
来自/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/connection\u adapters/abstract/database\u语句。rb:192:在“事务”中
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in“transaction”
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/transactions.rb:311:in`with\u transaction\u returning\u status'
from/usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active\u record/persistence.rb:215:in“update\u attributes”
Document Load (1.8ms) SELECT "documents".* FROM "documents" WHERE "documents"."user_id" = 19 ORDER BY "documents"."id" DESC LIMIT 1
(1.0ms) BEGIN
Product Load (41.7ms) SELECT "products".* FROM "products" WHERE "products"."id" = $1 LIMIT 1 [["id", 3640]]
Product Load (4.1ms) SELECT "products".* FROM "products" INNER JOIN "descriptions" ON "products"."id" = "descriptions"."product_id" WHERE "descriptions"."document_id" = 3552
User Load (7.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 19 LIMIT 1
Account Load (2.0ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 19 LIMIT 1
(0.9ms) SELECT COUNT(*) FROM "descriptions" WHERE "descriptions"."user_id" = 19
(1.2ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: User You have reached limit of 1
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_methods/dirty.rb:33:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `block in save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `save!'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/has_many_through_association.rb:85:in `save_through_record'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/has_many_through_association.rb:52:in `insert_record'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:496:in `block (2 levels) in concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:344:in `add_to_target'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:495:in `block in concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:493:in `each'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:493:in `concat_records'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:134:in `block in concat'
... 14 levels...
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/associations/builder/collection_association.rb:71:in `block in define_writers'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `each'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/persistence.rb:216:in `block in update_attributes'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in `transaction'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.13/lib/active_record/persistence.rb:215:in `update_attributes'
from (irb):2
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'