【问题标题】:Rails validates uniqueness scope for a has_many through tableRails 通过表验证 has_many 的唯一性范围
【发布时间】:2014-03-22 09:16:06
【问题描述】:

我为我的模型设置了 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

我是否错误地使用了唯一性验证器?我无法弄清楚这里的问题是什么......

【问题讨论】:

  • 啊...该死的。我知道发生了什么事!因为is_primary 是一个布尔值,所以它的假值也必须是唯一的,而不仅仅是真值。因此,因为 false 是默认值(或 nil),所以添加另一个关联失败......

标签: ruby-on-rails ruby-on-rails-3 validation associations unique


【解决方案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

【讨论】:

    猜你喜欢
    • 2021-05-13
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多