有些模型具有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, through:
?
UPD:在回答之前,请仔细阅读粗体中标记的句子。 Rails 4.2.1
答案 0 :(得分:2)
您必须创建自定义验证,如下所示:
cars.com/search;year=2010;model=true;brand=Mazda
这显示了一般的想法,您可以根据自己的需要进行调整。
<强>更新强>
这篇文章再次出现,我找到了填补空白的方法。
验证可以保持如上。我必须添加的是直接分配一组空类别的情况。那么,我该怎么做?
这个想法很简单:覆盖setter方法不接受空数组:
validate :has_categories
def has_categories
unless categories.size > 0
errors.add(:base, "There are no categories")
end
end
这将适用于每个作业,除非指定空集。然后,根本不会发生任何事情。不会记录任何错误,也不会执行任何操作。
如果您还想添加错误消息,则必须即兴发挥。将一个属性添加到将在铃声响起时填充的类中。 所以,简而言之,这个模型对我有用:
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
虽然,不会执行任何操作(跳过更新)。
答案 1 :(得分:0)
使用validates_associated
,官方文档为Here
答案 2 :(得分:-2)
如果您使用RSpec作为测试框架,请查看Shoulda Matcher。这是一个例子:
describe Event do
it { should have_many(:categories).through(:event_categories) }
end