2009-04-15 27 views
6

Tengo un modelo de usuario y un modelo de amistad.validates_associated y validates_presence_of no funciona como se esperaba con 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 

y uno de mis rspec prueba es

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 

La prueba no debería ser válido, porque no hay ningún usuario con user_id 9999. Pero la prueba es decir la amistad en el modelo es válido.

¿Por qué demonios?

EDIT:

Pero quiero probar como se ha mencionado -> sin asignar directamente al remitente. ¿No es eso posible?

documentación

Respuesta

11

Si desea que su modelo funcione de esa manera, cambiar esta situación:

validates_presence_of :receiver_id, :sender_id 

a esto:

validates_presence_of :receiver, :sender 
+0

No hace la diferencia. Funciona en consola, no funciona con pruebas (al menos no cuando se usan dispositivos) – Espen

+0

AFAIK, validates_presence_of en un nombre de asociación solo funciona como se espera cuando el objeto es un nuevo registro. Si está recuperando un dispositivo existente de db y modificando receiver_id directamente, esta prueba fallará a menos que primero configure el receptor como nulo. –

2

Los rieles de validates_associtated indica lo siguiente:

NOTA: Esta validación no fallará si no se ha asignado la asociación. Si desea asegurarse de que la asociación está presente y se garantiza su validez, también debe usar validates_presence_of.

No ha asignado la asociación. Modificar la prueba de la siguiente manera y debe pasar:

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 ..

después de encontrar sólo que esta entrada de blog y a-fix-ticket costumbre en los carriles Lighthouse:

Blog-entry with solution

Lighthouse-wont-fix-ticket

que me pasa a mi propia solución:

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 
Cuestiones relacionadas