繁体   English   中英

Rails ActiveRecord模型未在RSpec模型规范中更新

[英]Rails ActiveRecord Model not updating in RSpec model spec

这让我发疯。 我在不丢失上下文的情况下将其降至最低限度(我认为!)

我要做的就是检查更新值并将其保存到数据库时,该值是否已保存。 我想这样做是因为我需要编写其他代码来有条件地防止在before_save回调中执行此操作,并且在确定运行正常之前,我无法对其进行测试!

工厂和规格都在下面,我敢肯定它确实很愚蠢,但我只是想不通...

FactoryGirl.define do

  factory :programme do
    name 'Trainee Programme'
  end

  factory :membership do
    programme
  end

  factory :specialty do
    sequence(:name) { |n| "Specialty #{n}" }
  end

  factory :user do
    sequence(:email) { |n| "factorygirl-user-#{n}@remailer.org" }
    password 'password'
    password_confirmation 'password'
    factory :trainee, class: User do
      sequence(:email) { |n| "factorygirl-trainee-#{n}@remailer.org" }
      name 'Factory Girl Trainee'
      after(:create) do |user|
        FactoryGirl.create(:membership, user: user, start_date: 1.day.ago)
      end
    end
  end

end

describe Membership do

  let(:trainee) { FactoryGirl.create(:trainee) }

  it 'sets specialty' do
    puts trainee.current_membership.inspect
    trainee.current_membership.specialty = specialty
    puts trainee.current_membership.inspect
    trainee.current_membership.save!
    puts trainee.current_membership.inspect
    expect(trainee.current_membership.specialty).to eq(specialty)      
  end

end

规格失败,因为期望值显示为零。 当我运行代码时,我得到的调试输出是:

#<Membership id: 11, user_id: 11, programme_id: 11, start_date: "2015-03-10", end_date: nil, created_at: "2015-03-11 22:02:51", updated_at: "2015-03-11 22:02:51", options: {}, specialty_id: nil, membership_type_id: nil>
#<Membership id: 11, user_id: 11, programme_id: 11, start_date: "2015-03-10", end_date: nil, created_at: "2015-03-11 22:02:51", updated_at: "2015-03-11 22:02:51", options: {}, specialty_id: nil, membership_type_id: nil>
#<Membership id: 11, user_id: 11, programme_id: 11, start_date: "2015-03-10", end_date: nil, created_at: "2015-03-11 22:02:51", updated_at: "2015-03-11 22:02:51", options: {}, specialty_id: nil, membership_type_id: nil>

好像专业分配从未发生过??

尝试重新加载trainee ,例如

expect(trainee.reload.current_membership.specialty).to eq(specialty)

感谢BroiState和Mori给我一些指示,我得以确定它与持久性有关(特别是我的一种不尊重持久性的对象方法!)

trainee.current_membership的代码如下:

def current_membership
  return unless memberships.current.any?
  memberships.current.first
end

在会员中使用这些相关范围...

scope :started, -> { self.where("#{table_name}.#{_start_field}::TIMESTAMP < '#{Time.now}'") }
scope :not_ended, -> { self.where("#{table_name}.#{_end_field} IS NULL OR #{table_name}.#{_end_field}::TIMESTAMP > '#{Time.now}'") }
scope :current, -> { self.started.not_ended }

因此,每次致电trainee.current_membership都会给我一个“当前”会员记录的新实例

通过显式使用相同的对象,规范可以很好地通过,即:

it 'sets specialty' do
  membership = trainee.current_membership
  membership.specialty = specialty
  membership.save!
  expect(membership.specialty).to eq(specialty.reload)      
end

我能想到的唯一原因是speciality是一项新的,持久的唱片。 由于membership belongs_to :specialitymembership已被保留,因此既不会在分配时也不会在保存时保存关联的对象。 简而言之,在创建关联之前,请确保已保存speciality

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM