Ruby on rails Rails—一次具有单个值的自定义验证
所以我有两个模型:Ruby on rails Rails—一次具有单个值的自定义验证,ruby-on-rails,validation,Ruby On Rails,Validation,所以我有两个模型: class Tag < ActiveRecord::Base has_many :event_tags attr_accessible :tag_id, :tag_type, :value end class EventTag < ActiveRecord::Base belongs_to :tag attr_accessible :tag_id, :event_id, :region end 我想做的是编写一个自定义验证,在其中检查以查看: 每个事件id只
class Tag < ActiveRecord::Base
has_many :event_tags
attr_accessible :tag_id, :tag_type, :value
end
class EventTag < ActiveRecord::Base
belongs_to :tag
attr_accessible :tag_id, :event_id, :region
end
我想做的是编写一个自定义验证,在其中检查以查看:
- 每个事件id只有一个附加的“funLevel”标记类型,但可以有多个“通用”标记
t1 = EventTag.new(:tag_id => 1, :event_id =>777, :region => 'US')
t1.save # success
t2 = EventTag.new(:tag_id => 2, :event_id =>777, :region => 'US')
t2.save # failure
# because (event_id: 777) already has a tag_type of
# "funLevel" associated with it
t3 = EventTag.new(:tag_id => 4, :event_id =>777, :region => 'US')
t3.save # success, because as (tag_id:4) is not "funLevel" type
我想出了一个丑陋的解决方案:
def cannot_have_multiple_funLevel_tag
list_of_tag_ids = EventTag.where("event_id = ?", event_id).pluck(:tag_id)
if(Tag.where("tag_id in ?", list_of_tag_ids).pluck(:tag_type).include? "funLevel")
errors.add(:tag_id, "Already has a Fun Level Tag!")
end
作为rails的新手,有没有更好/更优雅/更便宜的方法?您的数据结构化方式意味着内置的rails验证可能不会对您有很大帮助如果
funLevel
属性可由EventTag
类直接访问,则可以使用如下内容:
# event_tag.rb
validate :tag_type, uniqueness: { scope: :event_id },
if: Proc.new { |tag| tag.tag_type == "funLevel" }
(不幸的是,通过快速测试,您似乎无法验证虚拟属性的唯一性。)
如果没有这一点,您可能无法使用自定义验证。对自定义验证的明显改进(假设您希望在EventTag
上进行验证)是不运行验证,除非EventTag
是funLevel
标记:
def cannot_have_multiple_funLevel_tag
return unless self.tag.tag_type == "funLevel"
...
end
是的,由于没有对数据库的完全控制,我不得不使用我所拥有的。我很喜欢你的自定义验证器,我不认为我可以使用标记模型作为属性。是的,关联添加了一系列方法,使得访问关联模型和与关联模型交互非常容易。如果您有阅读的心情,请查看Rails指南,尤其是。
def cannot_have_multiple_funLevel_tag
return unless self.tag.tag_type == "funLevel"
...
end