gpt4 book ai didi

ruby-on-rails - 如何在 has_many 的情况下通过 : association? 验证关联记录的存在

转载 作者:行者123 更新时间:2023-12-05 01:19:03 24 4
gpt4 key购买 nike

有模型具有 has_many through 关联:

class Event < ActiveRecord::Base
has_many :event_categories
has_many :categories, through: :event_categories

validates :categories, presence: true
end

class EventCategory < ActiveRecord::Base
belongs_to :event
belongs_to :category

validates_presence_of :event, :category
end

class Category < ActiveRecord::Base
has_many :event_categories
has_many :events, through: :event_categories
end

问题在于分配 event.categories = [] - 它会立即从 event_categories 中删除行。因此,先前的关联被不可逆转地破坏并且事件变为无效。

如何在 has_many 的情况下验证记录的存在,通过:

UPD:请在回答前仔细阅读标有粗体的句子。 rails 4.2.1

最佳答案

您必须创建自定义验证,如下所示:

validate :has_categories

def has_categories
unless categories.size > 0
errors.add(:base, "There are no categories")
end
end

这向您展示了总体思路,您可以根据自己的需要对其进行调整。

更新

这个帖子又出现了,我找到了填补空白的方法。

验证可以保持如上。我要补充的是直接分配一组空类别的情况。那么,我该怎么做呢?

思路很简单:重写setter方法不接受空数组:

def categories=(value)
if value.empty?
puts "Categories cannot be blank"
else
super(value)
end
end

这将适用于每个分配,但分配空集时除外。然后,什么都不会发生。不会记录任何错误,也不会执行任何操作。

如果您还想添加错误消息,则必须即兴发挥。将属性添加到将在铃声响起时填充的类。所以,长话短说,这个模型对我有用:

class Event < ActiveRecord::Base
has_many :event_categories
has_many :categories, through: :event_categories

attr_accessor :categories_validator # The bell

validates :categories, presence: true
validate :check_for_categories_validator # Has the bell rung?

def categories=(value)
if value.empty?
self.categories_validator = true # Ring that bell!!!
else
super(value) # No bell, just do what you have to do
end
end

private

def check_for_categories_validator
self.errors.add(:categories, "can't be blank") if self.categories_validator == true
end
end

添加了最后的验证后,如果您这样做,实例将无效:

event.categories = []

不过,不会执行任何操作(跳过更新)。

关于ruby-on-rails - 如何在 has_many 的情况下通过 : association? 验证关联记录的存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38616387/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com