Ruby on rails rails,rspec,应该验证的存在失败,setter调用了两次

Ruby on rails rails,rspec,应该验证的存在失败,setter调用了两次,ruby-on-rails,rspec2,shoulda,Ruby On Rails,Rspec2,Shoulda,在带有公司模型的简单rails应用程序中 class Company < ActiveRecord::Base # Attributes attr_accessible :name validates_presence_of :name def name=(s) self[:name] = s.upcase end end 调试表明name=(s)方法被调用了两次,一次调用'my_company',一次调用nil 我不明白为什么第二次打电话给nill。

在带有公司模型的简单rails应用程序中

class Company < ActiveRecord::Base

  # Attributes
  attr_accessible :name

  validates_presence_of :name

  def name=(s)
    self[:name] = s.upcase
  end
end
调试表明name=(s)方法被调用了两次,一次调用'my_company',一次调用nil

我不明白为什么第二次打电话给nill。 以下是使用的宝石:

gem 'rails', '3.2.13'
gem 'mysql2' 

group :development, :test do
  gem 'rspec-rails', '2.11.0' 
  gem 'shoulda-matchers', :require => false
end

原因可能是您在新的
name
方法中提到了
name

最好使用
write\u属性
方法作为您引用的文档

将其理解为:

 def name=(s)
   write_attribute(:name, s.upcase)
 end
  • Shoulda用于编写文档中提到的一个线性规格,如
    它{应该验证(:name)的存在}
    它{应该用消息(/不是可选的/)验证(:name)

    因此,您可以按如下方式编写更具可读性的规范:

    describe 'validations' do it {should validate_presence_of(:name)} end 描述“验证”是什么 它{应该验证存在(:name)} 结束
  • 关于名称字段的两个赋值问题:

  • 第一个赋值在规格的before(:each)块和
  • 是否应该存在状态验证器尝试为您指定的所有属性分配nil值,以验证是否存在,如果您的模型是:name
    您重写的name=方法将针对此nil值发生,它将引发一个错误,因为它无法将nil升格。由于同样的原因,上面显示的一个衬里规格也会失败。要解决此问题,可以将setter方法更改为dos.try(:upcase)。因此,它可以在零值上工作,不会引起任何问题

第二个方法name=修改name的值,因此我需要它。正确的方法应该是什么?它不能解释为什么第二个调用有一个nill值parameter@Alpha,是的,我知道您需要它,但您不需要编写该def,因为
attr\u accessible:name
已自动为您生成此方法。删除那个def,代码就可以工作了。难道你们不把attr\u accessible和attr\u accessor搞混了吗?如果您删除attr_accessible,您会得到“不能批量分配受保护的属性:名称”似乎也会像我那样显示出来it@Alpha是的,是我的错。但是你没有遵循同样的方法,你在新的
name
方法中提到了
name
,我认为这是错误的原因。查看文档,他们使用
write\u attribute
,这应该是正确的方法。查看文档的底部“您可以选择使用self[:attribute]=(value)和self[:attribute],而不是write\u attribute(:attribute,value)和read\u attribute(:attribute)。”我猜self[:name]=s.upcase对您的2是有效的。您从何处获得此信息?“状态验证程序是否应尝试为所有属性分配nil值”。我仍然不明白为什么这个方法被调用了两次。第一个调用名作为值,第二个调用它为null。@alpha,我检查了shoulda validate_presence_of_matcher的代码。有一个方法matches?,它在内部调用disallows_value of(blank_value,@expected_message)。如果您遵循此代码,您将看到在匹配中完成对nil值的赋值?AllowValueMatcher方法 describe 'validations' do it {should validate_presence_of(:name)} end