【问题标题】:FactoryGirl.create doesn't save Mongoid relationsFactoryGirl.create 不保存 Mongoid 关系
【发布时间】:2014-05-13 14:27:31
【问题描述】:

我有两个班级:

class User
  include Mongoid::Document

  has_one :preference
  attr_accessible :name
  field :name, type: String
end

class Preference
  include Mongoid::Document

  belongs_to :user
  attr_accessible :somepref
  field :somepref, type: Boolean
end

我有两个工厂:

FactoryGirl.define do
  factory :user do
    preference
    name 'John'
  end
end

FactoryGirl.define do
  factory :preference do
    somepref true
  end
end

创建User 后,两个文档都保存在数据库中,但Preference 文档缺少user_id 字段,因此当我从数据库中读取User 时,has_one 关系不起作用。

我目前已通过在User factory 中添加这段代码来修复它:

after(:create) do |user|
  #user.preference.save! #without this user_id field doesn't get saved
end

谁能向我解释为什么会发生这种情况,有没有更好的解决方法?

【问题讨论】:

标签: ruby ruby-on-rails-3 mongoid factory-bot


【解决方案1】:

如answer中所述:

为确保您始终可以立即回读您刚刚读取的数据 使用Mongoid写的,需要设置数据库会话选项

consistency: :strong, safe: true

这两个都不是默认的。

【讨论】:

    【解决方案2】:

    Mongoid 似乎在这里缺乏支持。

    当 FactoryGirl 创建用户时,它首先必须为该新用户创建首选项。由于新用户还没有 id,所以首选项也无法存储它。

    一般来说,当你尝试在一个操作中创建父子模型时,你需要两个步骤:

    1. 创建父级,持久化到数据库,以便获得一个 id。
    2. 为父级创建子级并将其持久化。

    第二步将在 after(:create) 块中结束。像这样:

    FactoryGirl.define do
      factory :user do
        name 'John'
    
        after(:create) do |user|
           preference { create(:preference, user: user) }
        end 
      end
    end
    

    【讨论】:

    • 谢谢!您的代码一开始不起作用,但我已经像这样重写了块内的行:user.preference = create(:preference, user: user) 并且它起作用了。
    • 如果我在 User 类中有 validates_presence_of :preference 怎么办?在执行 after(:create) 回调之前验证失败。
    • 糟糕,是的,我忘记了用户。至于验证:您可能需要使用 build 而不是 create。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多