【问题标题】:How do you create RoR Factory associations with accepts_nested_attributes_for?您如何使用 accept_nested_attributes_for 创建 RoR 工厂关联?
【发布时间】:2009-06-18 02:50:36
【问题描述】:

正如 Anton 指出的(感谢 Anton!)我的问题是测试中的关联缓存,看起来我确实在工厂中正确地创建了 nested_attribute。正确的语法是:

Factory.define :job do |f|
  ...
  f.vehicles_attributes [{:vin => "1", :model => "ford", :make => "escort"},{:vin => "1", :model => "ford", :make => "escort" }]
end

我在我的工作模型中使用accepts_nested__attributes_for,并且在每次更改模型时几乎失去我的弹珠“夹具潜水”后,我正试图迁移到工厂女孩。

我在下面发布了一堆代码,但我的问题很简单:

如何使用工厂创建nested_attributes?

我可以使用下面的代码创建一个 Job 实例,但我无法在我的单元测试中创建创建车辆。如果没有f.vehicles_attributes...,我的作业测试将无法通过验证。

我的单元测试产生以下结果:

  test "factory" do
    job = Factory(:job)
    assert(job.valid?)  # => true
    assert(job.vehicles.first.valid?) # => true
    vehicle = Factory(:vehicle)
    assert(vehicle.job.vehicles.size == 1) # => true
    assert_equal(vehicle.job.vehicles.first.vin, "2") # => FALSE.  <"1"> expected but was <"2">
  end

Factory.define :job do |f|
  ...
  f.vehicles_attributes [:vin => "1", :model => "ford", :make => "escort" ]
end

Factory.define :vehicle do |f|
  f.vin "2"
  f.model "ford"
  f.make "escort"
  f.association :job
end

class Job < ActiveRecord::Base
  has_many :vehicles, :dependent => :destroy
  validate :job_must_have_at_least_one_vehicle
  accepts_nested_attributes_for :vehicles, :allow_destroy => :true, :reject_if => proc { |vehicle_attributes| Job.insufficient_vehicle_input?(vehicle_attributes) }

  def job_must_have_at_least_one_vehicle
    errors.add(:vehicles, "need to be added") if self.vehicles.empty?
  end

  def self.insufficient_vehicle_input?(vehicle_attributes)
    vehicle_property_keys = vehicle_attributes.keys
    vehicle_property_keys.delete('_delete')
    vehicle_property_keys.delete('is_operational')
    vehicle_property_keys.delete('has_keys')
    vehicle_property_keys.each do |attribute_to_validate|
      if(!vehicle_attributes[attribute_to_validate].nil? && !vehicle_attributes[attribute_to_validate].empty?)
        return false
      end
    end
    return true
  end
end

【问题讨论】:

  • 顺便说一句,assert_equal 的正确用法是:assert_equal(expected, actual)

标签: ruby-on-rails factory-bot factories


【解决方案1】:

这都是关于关联缓存

这是它的工作原理:
1. Factory(:vehicle) 构建 vehicle 对象并创建 job 记录
2.之后填充vehicle.job_id并保存

vehicle.job 是从步骤 1 中指出的 job 对象。
所以,你只需要重新加载job

vehicle = Factory(:vehicle)
vehicle.job.reload.vehicles.size # => 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多