在 Rails 控制台中使用夹具查找助手

发布于 2024-12-20 16:22:13 字数 178 浏览 2 评论 0原文

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

我对谷歌甲骨文的查询没有发现任何结果,所以我没有屏住呼吸,但我希望这里有人知道一个秘密并愿意分享。

I frequently find that I'd like to be able to use the test fixture finders (eg. users(:david)) from the Rails console. Is there a specific Rails module I can load at the console prompt, or a gem I can install, that would make these available?

My queries of the Google Oracle have not turned anything up, so I'm not holding my breath, but I hope somebody here on SO knows a secret and is willing to share.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

筱武穆 2024-12-27 16:22:14

我自己想出来了。 这适用于 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: 的装置,则 users(:diane)从 Rails 控制台成功返回该用户。

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

Figured it out myself. This works with both IRB and Pry. Just needed to add the following lines to my .irbrc (and/or .pryrc) file.

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

Now, assuming that there's a test/fixtures/users.yml file and it contains a fixture named diane:, then users(:diane) from the Rails console successfully returns that user.

m_x's answer to the original question was helpful in reaching this point.

阳光的暖冬 2024-12-27 16:22:14

我希望我可以补充乔恩·加文的出色答案。这就像他的版本一样,但不使用 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: "[email protected]", password_digest: ...>

I wish I could add to Jon Garvin's excellent answer. This is just like his version but doesn't use method_missing (which is kinda scary in the global context and doesn't allow tab completion). Also, it waits until you call load_fixtures from irb before loading your fixtures.

Insert this in your .irbrc or just paste from here.

# 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

Example usage:

$ irb
irb(main):001:0> load_fixtures
=> ["oweto/spec"]
irb(main):002:0> users(:chuy)
=> #<User id: 242462757, email: "[email protected]", password_digest: ...>
往事风中埋 2024-12-27 16:22:14

有趣的问题。

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

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

Interesting question.

Don't know if that helps, but the actual logic to load fixtures seems to sit in active_record/fixtures.rb - especially have a look at ActiveRecord::TestFixtures::ClassMethods#fixtures which is the macro you usually call inside a TestCase child class.

The logic seems to be well contained within the ActiveRecord::TestFixtures module, so maybe you could try to roll your own class that includes that module and require it in the console. (it seems you will need to instantiate this class before acessing fixtures though, as the methods generated by the module are instance methods)

℡Ms空城旧梦 2024-12-27 16:22:14

我们将其与 FactoryGirl 结合使用,效果非常好。

如果您能够使用factory_girl,它具有一些非常好的功能,可以混合特征和工厂继承。对于 Factory Girl,通过规格访问它和通过控制台访问它非常相似。

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

如果你使用 bundler,你可以为你的开发和测试环境创建一个包含 Factory Girl 的 gem 组,那么你就不会在开发中使用控制台时需要需要它。

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

We use this to great effect with FactoryGirl.

If you are able to use factory_girl, it has some really nice features for mixing in traits and factory inheritance. With factory girl, accessing it via specs and accessing it via the console are very similar.

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

If you use bundler, you can create a gem group for your development and test environments that includes factory girl, then you will not need to require it when using the console in development.

group :development, :test do
  gem 'factory_girl'
end
非要怀念 2024-12-27 16:22:14

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

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

请参阅 文档 了解更多详细信息。

The other answer is incomplete, you need to tell FactoryGirl to load the definitions :

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

See the docs for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文