奇怪的是,我的模型通过验证就好了,并按预期运行,但是我仍然将错误呈现给视图。
# Controller
def up
@vote = Vote.create :vote => true, :voter => current_user, :voteable => Recipe.find(params[:id])
respond_to do |format|
format.js { render :json => {:model => 'vote', :success => @vote.valid?, :errors => @vote.errors }}
end
@vote.errors.clear # <= doesn't seem to help
end
我写的模型有一个自定义验证:
class Vote < ActiveRecord::Base
# ... associations etc.
validate :voter_voting_too_frequently?
private
def voter_voting_too_frequently?
last_vote_cast_by_voter = Vote.find_last_by_voter_id self.voter
unless last_vote_cast_by_voter.nil? || last_vote_cast_by_voter.created_at < 5.seconds.ago
errors.add_to_base("You can only vote every 5 seconds.")
end
end
end
最后,呈现给视图的响应:(毫无疑问,以js形式返回,但如果它位于<div>
中则相同)
{"errors":[["base","You can only vote every 5 seconds."]],"model":"vote","success":false}
即使它成功了,也会不断返回。
关于如何调试这个的想法?
答案 0 :(得分:1)
这个问题非常奇怪,与render => :json
有关。奇怪的是,当:success
块呈现json时,respond_to
键不能成为哈希中的第一个。
这是唯一需要改变的变化:
format.js { render :json => {:model => 'vote', :errors => @vote.errors.on_base, :success => @vote.errors.on_base.nil?} }
此外,我正在使用rails团队记录一张票。
答案 1 :(得分:0)
由于成功状态为false,因此看起来不会通过验证。
如果您看一下自定义验证,似乎“除非”关键字引起了一些混淆。
尝试:
if !last_vote_cast_by_voter.nil? && last_vote_cast_by_voter.created_at < 5.seconds.ago
errors.add_to_base ...
答案 2 :(得分:0)
我认为你的unless
陈述错了。就个人而言,我不习惯他们,所以我总是重写if语句
if last_vote_cast_by_voter.nil? == false && last_vote_cast_by_voter.created_at > 5.seconds.ago
看着这一行,我怀疑last_vote_cast_by_voter.created_at
应该低于5秒,因此我认为你的除非声明应改为
unless last_vote_cast_by_voter.nil? || last_vote_cast_by_voter.created_at > 5.seconds.ago
添加@vote.errors.clear
确实无济于事,因为视图已经在点上呈现......
如果这仍然不起作用,请尝试编写测试,然后投票。两票之间的时间应为1秒和10秒。例如
检查Vote.find_last_by_voter_id
是否正常工作。
如果所有这些测试都正常并且您的视图没有呈现,那么您的视图中会发生一些奇怪的事情,我想您应该发布一些有关视图的更多信息。