Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using fixture finder helpers within Rails console

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.

like image 947
Jon Garvin Avatar asked Dec 13 '11 01:12

Jon Garvin


3 Answers

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.

like image 108
Jon Garvin Avatar answered Oct 16 '22 08:10

Jon Garvin


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: ...>
like image 39
bronson Avatar answered Oct 16 '22 08:10

bronson


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)

like image 1
m_x Avatar answered Oct 16 '22 09:10

m_x