【问题标题】:Using fixture finder helpers within Rails console在 Rails 控制台中使用夹具查找器助手
【发布时间】:2012-01-18 23:37:04
【问题描述】:

我经常发现我希望能够从 Rails 控制台使用测试夹具查找器(例如users(:david))。是否有我可以在控制台提示符下加载的特定 Rails 模块,或者我可以安装的 gem,可以使这些模块可用?

我对 Google Oracle 的查询没有任何结果,所以我没有屏住呼吸,但我希望 SO 上有人知道一个秘密并愿意分享。

【问题讨论】:

  • 如果你想要一些 factory_girl 指针,请告诉我。我确信它足够强大,可以管理您当前在夹具中处理的任何复杂性。

标签: ruby-on-rails ruby console fixtures


【解决方案1】:

我自己想出来的。 这适用于 IRB 和 Pry只需将以下行添加到我的 .irbrc(和/或 .pryrc)文件中。

require 'active_record/fixtures'

def method_missing(method_name, *args, &block)
  if fixture_names.include?(method_name)
    method_name.to_s.singularize.titleize.constantize.find(fixture_id(args[0]))
  else
    super
  end
end

def fixture_id(label)
  ActiveRecord::FixtureSet.identify(label)
end

def fixture_names
  Dir["#{Rails.root}/test/fixtures/*.yml"].map { |filename| filename.match(/\/([^\/]+)\.yml/)[1].to_sym }
end

现在,假设有一个test/fixtures/users.yml 文件并且它包含一个名为diane: 的fixture,那么Rails 控制台中的users(:diane) 会成功返回该用户。

m_x 对原始问题的answer 有助于达到这一点。

【讨论】:

  • 很遗憾,此代码无法粘贴到控制台中。要解决此问题,请先粘贴 fixture_names 和 fixture_id 方法(这样 method_missing 不会递归到无穷大),然后粘贴其余的。
  • 对fixture_names 的一个小改动也将允许基于rspec 的fixture 工作:Dir["#{Rails.root}/{test,spec}/fixtures/*.yml"]
  • 仅供参考,Rails 4.2.1 弃用警告。使用ActiveRecord::FixtureSet 而不是ActiveRecord::Fixtures
【解决方案2】:

我希望我可以添加 Jon Garvin 的出色答案。这就像他的版本一样,但不使用 method_missing (这在全局上下文中有点可怕,并且不允许选项卡完成)。此外,它会等到您从 irb 调用 load_fixtures 后再加载您的灯具。

将其插入您的 .irbrc 或从此处粘贴。

# Loads all fixtures, then defines the Rails fixture helpers.
# For example: users(:jon) will load the jon fixture from fixtures/users.yml
def load_fixtures
  require 'active_record/fixtures'
  Dir["#{Rails.root}/{test,spec}"].each do |dir|
    Dir["#{dir}/fixtures/*.yml"].map { |filename| filename.match(/\/([^\/]+)\.yml/)[1].to_sym }.each do |name|
      ActiveRecord::FixtureSet.create_fixtures('spec/fixtures', name)
      define_method(name) { |*args|
        name.to_s.singularize.titleize.constantize.find(ActiveRecord::FixtureSet.identify(args[0]))
      }
    end
  end
end

示例用法:

$ irb
irb(main):001:0> load_fixtures
=> ["oweto/spec"]
irb(main):002:0> users(:chuy)
=> #<User id: 242462757, email: "chuy@example.com", password_digest: ...>

【讨论】:

    【解决方案3】:

    有趣的问题。

    不知道这是否有帮助,但加载夹具的实际逻辑似乎位于 active_record/fixtures.rb - 特别是看看 ActiveRecord::TestFixtures::ClassMethods#fixtures 这是您通常在 TestCase 子类中调用的宏。

    逻辑似乎很好地包含在 ActiveRecord::TestFixtures 模块中,因此也许您可以尝试滚动包含该模块的自己的类并在控制台中要求它。 (看起来你需要在访问fixture之前实例化这个类,因为模块生成的方法是实例方法)

    【讨论】:

    • 谢谢。我探索了 TextFixtures 代码并尝试了一些控制台实验,但无法让任何工作正常进行。当我有空闲时间时,我会继续尝试。
    【解决方案4】:

    我们在FactoryGirl 中使用这个效果非常好。

    如果你能够使用 factory_girl,它有一些非常好的特性可以混合特征和工厂继承。对于工厂女孩,通过规范访问和通过控制台访问非常相似。

    require 'factory_girl'
    user = FactoryGirl.create(:user)
    

    如果您使用bundler,您可以为您的开发和测试环境创建一个包含工厂女孩的gem组,那么您在开发中使用控制台时就不需要它了。

    group :development, :test do
      gem 'factory_girl'
    end
    

    【讨论】:

    • 我过去曾多次尝试过 FactorGirl,但当我需要在多个对象之间建立复杂的关系时,总是会碰壁。除了口中非常酸的工厂味之外,我不记得任何细节。无论如何,在大多数情况下,我希望在具有大量已建立和工作装置的成熟项目上执行此操作,并且尝试将所有这些都转换为 FactoryGirl 只是为了这个好处可能不是明智地使用我的时间。
    • 虽然这不是您想要的,但您可以按照此处列出的步骤操作:stackoverflow.com/a/7905915/107840。这利用了 rake db:fixtures:load 任务。
    • 我查看了 Fixture 源代码,它看起来并不简单。确实需要包含 TestFixtures 模块,如 m-x 所示。但是,您的实例需要有设置/拆卸回调,谁知道还有什么。再一次,我真的认为您应该使用 factory_girl 或其他替代夹具,如果在控制台中访问夹具数据是您真正需要的功能。如果你有兴趣,我可以给你一些建议,让你与 factory_girl 合作。
    【解决方案5】:

    另一个答案不完整,您需要告诉 FactoryGirl 加载定义:

    require 'factory_girl'
    FactoryGirl.find_definitions
    user = FactoryGirl.create(:user)
    

    有关详细信息,请参阅docs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 2011-10-26
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 2021-07-24
      相关资源
      最近更新 更多