【问题标题】:Rails ActiveRecord Model not updating in RSpec model specRails ActiveRecord 模型未在 RSpec 模型规范中更新
【发布时间】:2015-05-13 22:21:12
【问题描述】:

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

我要做的就是检查当我更新一个值并将其保存到数据库时,该值是否已保存。我想这样做是因为我需要编写一些其他代码来有条件地在 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

规范失败,因为 expect 看到一个 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>
#<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>

所以好像专业的分配从来没有发生过??

【问题讨论】:

  • speciality 定义在哪里?

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord rspec


【解决方案1】:

尝试重新加载trainee,例如

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

【讨论】:

  • 感谢指针,确保所有对象都按照 BroisState 的建议进行了实例化,然后重新加载我意识到问题出在哪里......已经发布了详细的答案(当然这是我的错!)
【解决方案2】:

我能想到的唯一原因是speciality 是一个新的非持久记录。由于membership belongs_to :specialitymembership 已经被持久化,它不会在分配和保存时保存关联的对象。简而言之,确保在创建关联之前保存speciality

【讨论】:

  • 感谢您的指点 - 我确保所有对象都是事先使用 FactoryGirl.create 创建的,结合 Mori 的建议帮助我弄清楚了它是什么
【解决方案3】:

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

trainee.current_membership的代码如下:

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

在 Membership 中使用这些相关范围...

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多