Фабричная девушка полиморфная ассоциация с атрибутом setter Error - PullRequest
0 голосов
/ 09 марта 2012

Я бился головой об этом некоторое время. Кто-нибудь, пожалуйста, спасите меня.

Сценарий

У меня есть следующие модели

class House < ActiveRecord::Base
  has_one :tenancy, :dependent => :destroy, :as => :tenant
end

class LeaseAgreement < ActiveRecord::Base
  has_many :tenancies
end

class Tenancy < ActiveRecord::Base
  belongs_to :tenant, :polymorphic => true
  belongs_to :lease_agreement

  def lease=(lease)
    if lease.rent_amount > 10000
      # do something here
    else
      # do something else here
    end

    self.lease_agreement = lease
  end
end

Мои фабрики

Factory.define :lease_agreement do |l|
  l.name "Foo"
  l.rent_amount 5000
end

Factory.define :tenancy do |t|
  t.name "Foo"
  t.association :tenant, :factory => :house
  t.after_build { |tenancy| tenancy.lease = Factory.create(:lease_agreement) }
end

тоже пробовал это

Factory.define :tenancy do |t|
  t.name "Foo"
  t.association :tenant, :factory => :house
  t.after_build { |tenancy| tenancy.lease = Factory.create(:lease_agreement, :tenant => tenancy) }
end

Оба способа в моих тестах спецификаций, когда я пытаюсь это сделать; @house = Factory(:house) Я получаю следующую ошибку

NoMethodError: undefined method `rent_amount' for nil:NilClass
from /home/kibet/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.5/lib/active_support/whiny_nil.rb:48:in `method_missing'
from /home/kibet/code/ruby/stuff/app/models/tenancy.rb:44:in `lease='

Как бы я поступил об этом?

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Похоже, проблема порядка операций, я думаю, что аренды устанавливается на ноль, прежде чем он оценивает ваш хук after_build, где аренда является законным экземпляром LeaseAgreement.

Ваш код не может обработать передаваемую нулевую аренду, что является допустимым значением, если вы хотите очистить ассоциацию. Попробуйте обработать ноль так:

class Tenancy < ActiveRecord::Base
  belongs_to :tenant, :polymorphic => true
  belongs_to :lease_agreement

  def lease=(lease)
    if lease.present? && lease.rent_amount > 10000
      # do something here
    else
      # do something else here
    end

    self.lease_agreement = lease
  end
end

Код в том виде, в котором он написан, всегда будет выдавать ошибку с передачей нулевого лизинга.

0 голосов
/ 13 марта 2012

Я думаю, что если вы напишите свою фабрику так:

Factory.define :tenancy do |t|
  t.name "Foo"
  t.association :tenant, :factory => :house
  t.after_build { |tenancy| tenancy.lease = Factory.create(:lease_agreement) }
end

Ваш :lease_agreement будет создан правильно, и он должен работать. Нет tenancy для lease_agreement.

...