使用rspec,validates_associated和validates_presence_of无法正常工作?

时间:2009-04-15 17:51:06

标签: ruby-on-rails ruby

我有一个用户模型和一个友谊模型。

class Friendship < ActiveRecord::Base
  belongs_to :sender, :class_name=>'User', :foreign_key=>'sender_id'
  belongs_to :receiver, :class_name=>'User', :foreign_key=>'receiver_id'

  validates_presence_of :receiver_id, :sender_id
  validates_associated :receiver, :sender
end

class User < ActiveRecord::Base
  has_many :sent_friendships, :class_name => "Friendship", :foreign_key => "sender_id", :dependent => :destroy
  has_many :received_friendships, :class_name => "Friendship", :foreign_key => "receiver_id", :dependent => :destroy
end

我的一个rspec测试是

describe Friendship do

  before(:each) do
    @valid_attributes = {
      :sender_id => 1,
      :receiver_id => 2,
      :accepted_at => nil
    }
  end

  it "should not be valid with non-existant receiver_id" do
    f = Friendship.new(@valid_attributes)
    f.receiver_id = 99999
    f.should_not be_valid
  end
end

测试不应该是有效的,因为没有User with user_id 9999.但是测试说友谊模型是有效的。

为什么地狱?

编辑:

但是我想像上面提到的那样测试 - &gt;没有直接分配发件人。那可能吗?

4 个答案:

答案 0 :(得分:11)

如果您希望您的模型以这种方式工作,请更改此:

validates_presence_of :receiver_id, :sender_id

到此:

validates_presence_of :receiver, :sender

答案 1 :(得分:2)

validates_associtated的Rails文档说明如下:

  

注意:如果尚未分配关联,则此验证不会失败。如果您想确保关联存在且保证有效,您还需要使用validates_presence_of。

你没有指定协会。按如下方式修改您的测试,它应该通过:

it "should not be valid with non-existant receiver_id" do
  f = Friendship.new(@valid_attributes)
  f.receiver_id = 99999
  f.receiver = nil  # Note this line
  f.should_not be_valid
end

答案 2 :(得分:2)

还有一个旧的插件浮动,这样做...... validates_existence_of

http://blog.hasmanythrough.com/2007/7/14/validate-your-existence

答案 3 :(得分:1)

嗯..

在我发现只有这个博客条目和rails lighthouse中的wont-fix-ticket之后:

Blog-entry with solution

Lighthouse-wont-fix-ticket

我切换到我自己的解决方案:

class Friendship < ActiveRecord::Base
  belongs_to :sender, :class_name=>'User', :foreign_key=>'sender_id'
  belongs_to :receiver, :class_name=>'User', :foreign_key=>'receiver_id'

  validates_presence_of :receiver_id, :sender_id

  validate :sender_exists
  validate :receiver_exists

  protected
  def sender_exists
    errors.add("sender_id", "not existant") unless User.exists?(self.sender_id)
  end  
end