Search code examples
ruby-on-railsruby-on-rails-4yamlfixtures

Access Attribute of Rails Test Fixture in Associated FixtureSet


Background

My application defines a one-to-many relationship between Employee and Company models. I've assigned the Employee fixture a company using the label of the Company fixture (37_signals). However, I also need to assign the company_uuid, which is generated by SecureRandom.uuid.


Example

app/models/

employee.rb

class Employee
  belongs_to :company
end

company.rb

class Company
  has_many :employees
end

test/fixtures/

employees.yml

employee:
  name: dhh
  company: 37_signals 
  company_uuid: <%= "Access the 37_signals company fixture's uuid here!" %>

companies.yml

37_signals:
  name: $LABEL
  company_uuid: <%= SecureRandom.uuid %>

Question

How can I access the attribute of a Fixture in another FixtureSet?


Attempted

I've attempted to use the following lines as solutions:

company_uuid: <%= ActiveRecord::FixtureSet.identify(:37_signals).company_uuid %>

The above finds the company's primary key id value, then calls the company_uuid method, which is undefined for the integer. This is invalid.

company_uuid: <%= companies(:37_signals).company_uuid %>

The above finds reports undefined method 'companies' for main:Object

Is there a conventional way to solve this problem?


Solution

  • Hmmm, the first option should be to DRY out the data, so it only exists in one place. You could do this with a delegate so that employee.company_uuid will always be answered by employee.company.company_uuid.

    If you really need it in the Employee model, the next best choice would be to use a callback (like before_validate or after_save depending on your use-case), that copies the value from the Company to the Employee object. You want to eliminate chances for the data value to diverge from what it's true source should be.

    Finally, you could extract all the UUIDs into a hash accessible to both fixtures at the time of creation, and set both values like: company_uuid: <%= UUIDs['37_signals'] %> ...or similar