Rails 2 foxy fixtures and named_scope/has_finder closure issues

Posted by Tim Connor Fri, 11 Jul 2008 23:20:00 GMT

If you are using a has_finder (or possibly named_scope, I haven’t confirmed this myself), remember that unless you wrap your condition => in a lambda it is going to be evaluated early – or at least earlier than fixture creation, it seems. At work we had a case where one model had a finder that depended on its belong_to being in a subset of another, basically:

has_finder :all_active, {  :conditions => {:status_id => Status.active_ids} }

This work in production, where the ids don’t change, but since we are using the newer fixture approach on this model the ids are created dynamically. Given how fixtures load, the table will probably be populated with the old values, at parse time for that class, then the test will run, and the fixtures will reload, and they will not match anymore.

This is easily fixed, when you realize what is happening:

has_finder :all_active, lambda {|| {  :conditions => {:status_id => OtherModel.active_ids} }}

Backing up or transfering your data via YAML 4

Posted by Tim Connor Mon, 26 Mar 2007 21:27:00 GMT

Thanks to http://snippets.dzone.com/tag/fixtures. No warranties and no guarantees it’ll work on your full DB. I’m just using it for transferring around my starting data during dev.

Yes, I know part of this can be done with db:fixtures:load – but I don’t want to use ‘tests/fixtures’

lib/tasks/fixtures.rake

namespace :db do
  namespace :YAML do
    desc 'Create YAML backup fixtures'
    task :backup => :environment do
      sql = "SELECT * FROM %s" 
      skip_tables = ["schema_info", "sessions"]
      ActiveRecord::Base.establish_connection
      tables = ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : ActiveRecord::Base.connection.tables - skip_tables
      tables.each do |table_name|
        i = "000" 
        File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)
          file.write data.inject({}) { |hash, record|
            hash["#{table_name}_#{i.succ!}"] = record
            hash
          }.to_yaml
        end
      end
    end

    desc "Load db/fixtures in fixtures_load_order" 
    task :restore => :environment do
      ActiveRecord::Base.establish_connection
      require 'active_record/fixtures'
      Fixtures.create_fixtures("db/fixtures", ActiveRecord::Base.configurations[:fixtures_load_order])
      puts "Loaded these fixtures: " + ActiveRecord::Base.configurations[:fixtures_load_order].collect { |f| f.to_s }.join(', ')
    end
  end
end
config/environments.rb

ActiveRecord::Base.configurations[:fixtures_load_order] = [
  :users, 
  :locations, 
  :reports, 
  :conditions
]

Testing plugins : loading fixtures and environment

Posted by Tim Connor Sun, 22 Oct 2006 21:44:00 GMT

One of the first things I learned working on the typo-permalink-with-id plugin was how to load fixtures from a plugin. I had previously just been mocking out ActiveRecord, but the Typo object model is complicated enough that it was easier to just schlup their envirnment.rb and then load their fixtures into my tests.

require 'test/unit'
require 'active_record'
require 'active_record/fixtures'
RAILS_ENV = "test" 
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))

class TypoPermalinkWithIdTest < Test::Unit::TestCase

  def setup
    fixtures_dir = File.expand_path(File.join(File.dirname(__FILE__), '../../../../test/fixtures'))
    Fixtures.create_fixtures(fixtures_dir, File.basename("blogs.yml", '.*'))
    Fixtures.create_fixtures(fixtures_dir, File.basename("users.yml", '.*'))
  end

  def test_fixtures_loaded
    assert_not_nil Blog.find_by_id(1), "blogs.yml not loaded" 
    assert_not_nil User.find_by_id(1), "users.yml not loaded" 
  end

Edit: This idea slightly cribbed from Loading Fixtures in a Migration