And*_*ite 10 activerecord ruby-on-rails
我的完整代码可以在https://github.com/andyw8/simpleform_examples上看到
我有一个ProductCategory带有以下验证的连接模型:
validates :product, presence: true
validates :category, presence: true
Run Code Online (Sandbox Code Playgroud)
我的Product模型有以下关联:
has_many :product_categories
has_many :categories, through: :product_categories
Run Code Online (Sandbox Code Playgroud)
当我尝试使用类别创建新产品时,@product.save!控制器中的调用将失败:
Validation failed: Product categories is invalid
Run Code Online (Sandbox Code Playgroud)
当我删除验证时,一切正常,连接模型正确保存.
我正在使用,strong_parameters但我不认为这应该与这个问题有关.
cha*_*sto 11
这是回调链中的"竞争条件".
当您创建产品时,它在保存之前没有任何ID,因此product在范围内没有ProductCategory.
Product.new(name: "modern times", category_ids:[1, 2]) #=> #<Product id: nil >
Run Code Online (Sandbox Code Playgroud)
在验证阶段(保存之前),ProductCatgory不能将任何id分配给它的外键product_id.
这就是你有关联验证的原因:这样验证就发生在整个事务的范围内
更新:如评论中所述,您仍然无法确保产品/类别的存在.有很多方法取决于你想要这样做的原因(例如通过某种形式直接访问ProductCategory)
validates :product, presence: true, if: :direct_access?validates :product, presence: true, on: "update"......但事实上,这些都是简单的妥协或变通办法 @product.create(params)
指定inverse_of有关您的加盟模式已被证明可以解决这个问题:
https://github.com/rails/rails/issues/6161#issuecomment-6330795 https://github.com/rails/rails/pull/7661#issuecomment-8614206
简化示例:
class Product < ActiveRecord::Base
has_many :product_categories, :inverse_of => :product
has_many :categories, through: :product_categories
end
class Category < ActiveRecord::Base
has_many :product_categories, inverse_of: :category
has_many :products, through: :product_categories
end
class ProductCategory < ActiveRecord::Base
belongs_to :product
belongs_to :category
validates :product, presence: true
validates :category, presence: true
end
Product.new(:categories => [Category.new]).valid? # complains that the ProductCategory is invalid without inverse_of specified
Run Code Online (Sandbox Code Playgroud)
改编自:https : //github.com/rails/rails/issues/8269#issuecomment-12032536
| 归档时间: |
|
| 查看次数: |
3009 次 |
| 最近记录: |