6 Stimmen

validates_associated und validates_presence_of funktionieren nicht wie erwartet mit rspec?

Ich habe ein Benutzer-Modell und ein Freundschafts-Modell.

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

und einer meiner rspec-Tests lautet

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

Der Test sollte nicht gültig sein, da es keinen User mit der user_id 9999 gibt. Aber der Test sagt, dass das Freundschaftsmodell gültig ist.

Warum zum Teufel?

EDIT:

Aber ich möchte wie gesagt testen -> ohne den Absender direkt zuzuordnen. Ist das nicht möglich?

11voto

Elliot Nelson Punkte 10861

Wenn Sie wollen, dass Ihr Modell auf diese Weise funktioniert, ändern Sie dies:

validates_presence_of :receiver_id, :sender_id

dazu:

validates_presence_of :receiver, :sender

2voto

Christoph Schiessl Punkte 6778

Die Rails-Dokumentation für validates_associtated lautet wie folgt:

HINWEIS: Diese Überprüfung schlägt nicht fehl, wenn die Assoziation noch nicht zugewiesen wurde. Wenn Sie sicherstellen wollen, dass die Assoziation sowohl vorhanden als auch garantiert gültig ist, müssen Sie auch validates_presence_of verwenden.

Sie haben die Assoziation noch nicht zugeordnet. Ändern Sie Ihren Test wie folgt, und er sollte erfolgreich sein:

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

2voto

Ian Terrell Punkte 10459

Es gibt auch ein altes Plugin, das dies tut... validates_existence_of .

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

1voto

BvuRVKyUVlViVIc7 Punkte 11466

Hm..

nachdem ich nur diesen Blogeintrag und ein Wont-fix-Ticket im Schienen-Leuchtturm gefunden habe:

Blog-Eintrag mit Lösung

Leuchtturm-wird-nicht-fixiert-Ticket

Ich bin zu meiner eigenen Lösung übergegangen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X