如果重复,Rails不会保存

时间:2014-02-16 21:16:28

标签: ruby-on-rails ruby activerecord

我有一个有点复杂的Rails模型设置,我会尽量简化。此设置的目标是能够拥有长期存在的对象(PersonPet),但它们之间的关系每年都会通过TemporalLink更改。基本上,我有这些模型:

class Person < ActiveRecord::Base
  include TemporalObj

  has_many :pet_links, class_name: "PetOwnerLink"
  has_many :pets, through: :pet_links
end

class Pet < ActiveRecord::Base
  include TemporalObj

  has_many :owner_links, class_name: "PetOwnerLink"
  has_many :owners, through: :owner_links
end

class PetOwnerLink < ActiveRecord::Base
  include TemporalLink

  belongs_to :owner
  belongs_to :pet
end

以及这些问题:

module TemporalLink
  extend ActiveSupport::Concern

  # Everything that extends TemporalLink must have a `year` attribute.
end

module TemporalObj
  extend ActiveSupport::Concern

  # Everything that extends TemporalObj must have a find_existing() method.

  ####################
  # Here be dragons! #
  ####################
end

理想的行为是:

  • 创建TemporalObjPetPerson)时:

    1)根据某些条件,使用find_existing()检查是否存在现有的。

    2)如果找到现有副本,请不要执行创建,但仍会对关联对象执行必要的创建。 (这似乎是一个棘手的部分。

    3)如果未找到重复,请执行创建。

    4)[现有魔法已自动创建必要的TemporalLink个对象。]

  • 销毁TemporalObj

    1)检查对象是否存在超过一年。 (这在实际中比在这个例子中更简单。)

    2)如果对象仅在一年内存在,则将其销毁并关联TemporalLink s。

    3)如果对象存在超过一年,只需销毁其中一个TemporalLink

我的问题是我在许多TemporalObj上都有唯一性验证,因此当我尝试创建新的复制时,验证会失败,然后才能执行任何around_create魔法。关于我如何能够解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:2)

您可以(并且应该)在此处使用Rails的内置验证。您所描述的是validates_uniqueness_of,您可以将其包含在多个列中。

例如:

class TeacherSchedule < ActiveRecord::Base
  validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
end

http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of

答案 1 :(得分:0)

回应JacobEvelyn的评论,这就是我所做的。

  1. 像这样创建了自定义验证
  2.       def maintain_uniqueness
            matching_thing = Thing.find_by(criteria1: self.criteria1, criteria2: self.criteria2)
            if !!matching_thing
              self.created_at = matching_thing.created_at
              matching_thing.delete
            end
            true
          end
    
    1. 将其添加到我的验证中

      validate :maintain_event_uniqueness

    2. 有效。