考虑以下代码:
campaign_spec.rb:
describe Campaign do
before :each do
@campaign = Campaign.new
end
it { should validate_presence_of :position }
end
活动.rb:
class Campaign < ActiveRecord::Base
attr_accessible :position
validates :position, presence: true
default_scope order(:position)
before_validation :next_position
# sets the position to the next id (1 if none exist) before validation
def next_position
if self.position.blank?
self.position = Campaign.select("coalesce(max(position),0) + 1 as position").reorder(nil).first.position
end
end
end
规格输出:
Failures:
1) Campaign should require position to be set
Failure/Error: it { should validate_presence_of :position }
Expected errors to include "can't be blank" when position is set to nil, got errors: ["name can't be blank (nil)"]
# ./spec/models/campaign_spec.rb:9:in `block (2 levels) in <top (required)>'
根据我的模型所说,我应该能够在不给它定位的情况下创建Campaign
。如果在验证前不存在,则设置位置。那么,为什么我的规范没有通过呢?我在想,也许它没有调用我的before_validation
方法?
should validate_presence_of
将属性的值设置为nil,然后运行验证。由于它为零,nil.blank?
返回true
,因此执行回调,将其设置回某个值,因此发现验证不起作用。
事实是,如果您确信该字段从不为空,则不需要验证该字段。相反,编写测试以检查当设置为nil时是否确实自动填充了它。
it 'populates position if blank before validations' do
subject.position = nil
subject.valid?
subject.position.should_not be_nil
end