Showing posts with label girl. Show all posts
Showing posts with label girl. Show all posts

Sunday, August 15, 2010

Factory Girl in Development

Some many developers use Factory Girl as a replacement to Fixtures and they depend on this gem in Test cases writing.

But Factory Girl can be very useful also in development and can be used in order to generate a bunch of dummy data with different specs for showing your work and reviewing all its details.

The problem we face is that Factory Girl can generate more records in tables that should have their data unchanged such as Countries table.

For example:

Factory.define :user do |f|
  f.association :country
end

Factory.define :job do |f|
  …
  f.association :user
end

Now, when we run this piece of code that generates 10 jobs

10.times { Factory.create(:job) }

we will get 10 countries auto-generated
violating the rule we wish to maintain which is having the countries table as it is

To workaround this problem without causing any changes in the code written previously, i came up with that solution

class Factory
  class << self
    alias_method :create_original, :create
    
    def create(name, overrides = {})
      if name.to_s == 'country'
        country = Country.first
        return country if country
      end

      create_original(name, overrides)
    end
  end
end

The logic introduced in the above script is simply adding a layer before creation that checks if the created object of certain type and if that type is desired to not be generated, we return the first entry we have in the DB else we do the normal creation

You can add this script in a file and load it in the development environment and use Factory Girl safely without fearing of generating data for tables that should remain as lookup tables

Enjoy :)

Monday, August 9, 2010

Factory Girl & Polymorphic Associations

Suppose you have a case like that

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic => true
end

class Listing < ActiveRecord::Base
  has_one :address, as => :addressable
end

class Customer < ActiveRecord::Base
  has_one :address, as => :addressable
end

Now in your factories you will have something like that

Factory.define :listing do |f|
  f.association :address
end

since addressable is required, we choose it to be by default related to a customer unless else stated

Factory.define :address do |f|
  f.association :addressable, :factory => :customer
end

right now if you tried to use the Listing Factory, you will get an address associated with dummy customer and no effect on your side

How can this be fixed ?

Factory.define :listing do |f|
  f.after_build do |listing|
    listing.address = Factory.create(:address, :addressable => listing)
  end
end

This was the only solution i found after searching for a while
which is a good solution and doesn't need a lot of work to be done