我有一个有点复杂的Rails模型设置,我会尽量简化。此设置的目标是能够拥有长期存在的对象(Person
,Pet
),但它们之间的关系每年都会通过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
理想的行为是:
创建TemporalObj
(Pet
,Person
)时:
1)根据某些条件,使用find_existing()
检查是否存在现有的。
2)如果找到现有副本,请不要执行创建,但仍会对关联对象执行必要的创建。 (这似乎是一个棘手的部分。)
3)如果未找到重复,请执行创建。
4)[现有魔法已自动创建必要的TemporalLink
个对象。]
销毁TemporalObj
:
1)检查对象是否存在超过一年。 (这在实际中比在这个例子中更简单。)
2)如果对象仅在一年内存在,则将其销毁并关联TemporalLink
s。
3)如果对象存在超过一年,只需销毁其中一个TemporalLink
。
我的问题是我在许多TemporalObj
上都有唯一性验证,因此当我尝试创建新的复制时,验证会失败,然后才能执行任何around_create
魔法。关于我如何能够解决这个问题的任何想法?
答案 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的评论,这就是我所做的。
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
将其添加到我的验证中
validate :maintain_event_uniqueness
有效。