我为我的模型设置了has_many :through
类型关联:
class Place < ActiveRecord::Base
has_many :place_subcategory_relations, dependent: :destroy
has_many :place_subcategories, through: :place_subcategory_relations, uniq: true
end
class PlaceSubcategory < ActiveRecord::Base
has_many :place_subcategory_relations, dependent: :restrict
has_many :places, through: :place_subcategory_relations, uniq: true
end
class PlaceSubcategoryRelation < ActiveRecord::Base
belongs_to :place
belongs_to :place_subcategory
validates :is_primary, uniqueness: {scope: :place_id}
end
问题是,当我尝试将另一个子类别添加到某个地方时:
place.place_subcategories << PlaceSubcategory.find(84)
我收到此错误:
(0.2ms) BEGIN
PlaceSubcategoryRelation Exists (0.6ms) SELECT 1 AS one FROM "place_subcategory_relations" WHERE ("place_subcategory_relations"."is_primary" IS NULL AND "place_subcategory_relations"."place_id" = 169) LIMIT 1
(0.2ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Is primary has already been taken
我还尝试先创建PlaceCategoryRelation,但没有提交任何内容:
p.place_subcategory_relations << PlaceSubcategoryRelation.new(place_id: p.id, place_subcategory_id: PlaceSubcategory.find(84).id)
(0.2ms) BEGIN
PlaceSubcategoryRelation Exists (0.6ms) SELECT 1 AS one FROM "place_subcategory_relations" WHERE ("place_subcategory_relations"."is_primary" IS NULL AND "place_subcategory_relations"."place_id" = 169) LIMIT 1
(0.2ms) COMMIT
我是否错误地使用了唯一性验证器?我无法弄清楚这里的问题是什么......
答案 0 :(得分:1)
解决!
问题在于,因为is_primary
是一个布尔值,所以它的假值也必须是唯一的,而不仅仅是真值。因此,当存在is_primary = false
的另一个与is_primary = false
的新关联时,它会失败,就像它应该的那样。
我通过使用它来验证它来解决它:
validates :is_primary, uniqueness: {scope: :place_id}, if: ->{self.is_primary && self.class.where(place_id: self.place_id, is_primary: true).length > 0}
编辑:我想这也有效,而且更简单:
validates :is_primary, uniqueness: {scope: :place_id}, if: :is_primary