当前位置:  开发笔记 > 后端 > 正文

has_many同时尊重factory_girl中的构建策略

如何解决《has_many同时尊重factory_girl中的构建策略》经验,为你挑选了3个好方法。

我用继承和所有这些正确地写了它.我的提交在这里和这里合并.

它现在在FactoryGirl 1.2.3中,哇!



1> fowlduck..:

我用继承和所有这些正确地写了它.我的提交在这里和这里合并.

它现在在FactoryGirl 1.2.3中,哇!



2> fowlduck..:

我最终修补工厂女孩允许after_buildafter_create回调.

履行

Factory.class_eval do
  def run (proxy_class, overrides) #:nodoc:
    proxy = proxy_class.new(build_class)
    proxy.callbacks = @callbacks
    overrides = symbolize_keys(overrides)
    overrides.each {|attr, val| proxy.set(attr, val) }
    passed_keys = overrides.keys.collect {|k| Factory.aliases_for(k) }.flatten
    @attributes.each do |attribute|
      unless passed_keys.include?(attribute.name)
        attribute.add_to(proxy)
      end
    end
    proxy.result
  end

  def after_create(&block)
    @callbacks ||= {}
    @callbacks[:after_create] = block
  end

  def after_build(&block)
    @callbacks ||= {}
    @callbacks[:after_build] = block
  end
end

Factory::Proxy.class_eval do
  attr_accessor :callbacks

  def run_callback(name)
    callbacks && callbacks[name] && callbacks[name].call(@instance)
  end
end

Factory::Proxy::Build.class_eval do
  def result
    run_callback(:after_build)
    @instance
  end
end

Factory::Proxy::Create.class_eval do
  def result
    run_callback(:after_build)
    @instance.save!
    run_callback(:after_create)
    @instance
  end
end

这可能是一个邪恶的双胞胎或只是你需要的扩展.

示例用法

# Models
class User < ActiveRecord::Base
  has_many :items
end

class Items < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user_id
end

# Factories
Factory.define(:user) do |u|
  u.name "foo"
end

Factory.define(:user_with_items, :parent => :user) do |u|
  u.after_build do |o|
    o.items = [Factory.build(:item, :user => o), Factory.build(:item, :user => o)]
  end
end

Factory.define(:item) do |i|
  i.color "red"
end

Factory.define(:item_with_user, :parent => :user) do |i|
  i.association(:user)
end

# Run
user = Factory(:user_with_items)
user.items(true) # Shows the two saved items

希望这可以帮助将来的某个人.我可能会尝试将这个提交给思想机器人,但是他们的bug跟踪器中已经有一些关于这个主题的陈旧故障了.



3> 小智..:

我通常喜欢将构建和创建分开,因此我仍然可以构建对象而无需访问数据库。

Factory.define(:user_with_items, :parent => :user) do |u|
  u.after_build do |u|
    u.items = (1..2).map {Factory.build(:item, :user => u)}
  end
  u.after_create do |u|
    u.items.each {|i| i.save!}
  end
end

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有