2009-04-15 8 views
6

J'ai un modèle d'utilisateur et un modèle d'amitié.validates_associated et validates_presence_of ne fonctionnent pas comme prévu avec rspec?

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 

et l'un de mes rspec test est

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 

Le test valide ne devrait pas être, parce qu'il n'y a pas d'utilisateur avec user_id 9999. Mais le test est dit l'amitié modèle est valide.

Pourquoi diable?

EDIT:

Mais je veux tester comme mentionné -> sans attribuer directement l'expéditeur. N'est-ce pas possible ??

Répondre

11

Si vous voulez que votre modèle fonctionne de cette façon, changer ceci:

validates_presence_of :receiver_id, :sender_id 

à ceci:

validates_presence_of :receiver, :sender 
+0

ne fait pas de différence. Fonctionne en console, ne fonctionne pas avec testing (du moins pas en utilisant des projecteurs) – Espen

+0

AFAIK, validates_presence_of sur un nom d'association ne fonctionne que lorsque l'objet est un nouvel enregistrement. Si vous récupérez un appareil existant à partir de db et que vous modifiez receiver_id directement, alors ce test échouera à moins que vous ne définissiez d'abord le récepteur comme nul. –

2

La documentation Rails pour validates_associtated indique ce qui suit:

REMARQUE: Cette validation ne manquera pas si l'association n'a pas été affecté. Si vous voulez vous assurer que l'association est présente et garantie, vous devez également utiliser validates_presence_of.

Vous n'avez pas associé l'association. Modifier votre test comme suit et il doit passer:

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 
1

Hm ..

après avoir trouvé que cette entrée de blog et un wont-fix ticket dans des rails phare:

Blog-entry with solution

Lighthouse-wont-fix-ticket

je suis passé à ma propre solution:

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 
Questions connexes