我遇到了一个自定义验证问题,它会检查关联对象的数量。有两个类,Event
和Guest
。
当用户创建新活动时,他可以选择一些邀请的来宾。保存后,我想检查一下受邀嘉宾的数量。
更新现有事件时,验证工作正常。但是在创建新事件时,验证失败,因为self.guests.count
返回0
。
在控制器中,我检查了所选的客人是否以相同的方式传递给模型:params[:event][:guest_ids]
。
如果发生更新,我可以看到在调用验证块之前,更新关联表的SQL INSERT INTO
被添加到事务队列中。但是在新事件的情况下,SQL INSERT
在验证失败之前不会显示。
我在这里缺少什么?我正在考虑一些解决方法,但我确信有一种正确的方法来实现它。
Rails版本是4.2.6
class Event < ActiveRecord::Base
has_and_belongs_to_many :guests
validate :check_guestlist
def check_guestlist
guest_count=self.guests.count
if guest_count < 3
errors.add(“Please invite more guests”)
end
end
class Guest < ActiveRecord::Base
has_and_belongs_to_many :events
end
class EventsController < ApplicationController
def create
@event = current_user.events.new(event_params)
respond_to do |format|
if @event.save
format.html { redirect_to @event, notice: 'Event was successfully created.' }
else
flash.now[:alert]='Event not saved.'
format.html { render action: "new" }
end
end
end
def update
@event = current_user.events.find(params[:id])
respond_to do |format|
if @event.update_attributes(event_params)
format.html { redirect_to @event, notice: 'Event was successfully updated.' }
else
flash.now[:alert]='Changes not saved.'
format.html { render action: "edit" }
end
end
end
end
答案 0 :(得分:0)
我设法通过替换自定义验证中的一行代码来解决此问题。 如果我更换
guest_count=self.guests.count
与
guest_count=self.guests.to_a.count
我得到了预期的结果。 在更新的情况下,两个表达式都返回相同的结果。但是在新记录的背景下,只有第二个响应预期。 不过,我仍然不明白为什么第一个版本没有用。
答案 1 :(得分:0)
好的,self.guests.count在创建时不起作用的原因是这实际上是在进行数据库查询,具有事件范围。
SELECT COUNT(*) FROM
{客人{1}} {客人{1}}的event_id WHERE
现在当然失败了,因为验证发生在客人保存之前。现在更新它是有效的,因为在数据库中有条目。但是,验证是检查错误的信息 - 数据库中的访客数量不一定与self.guests的数量相匹配 - 您可以添加一个尚未保存的访客。
您的解决方案确实有效,但我个人认为最好将其编写为:
.
= 1
将测试来宾数组的大小 - 例如validates :guests, length: { minimum: 3, message: 'Please invite more guests' }
实际上与length