Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails loading fixtures with wrong foreign keys

I'm writing a simple app using rails 4.1.0. I created two models called Serie and Event, with a one to many relationship between them (as in one Serie has many Events).

class Serie < ActiveRecord::Base
  has_many :events
end

class Event < ActiveRecord::Base
  belongs_to :serie
end

I created the following fixture files for these models:

#series.yml
---
Serie1:
  name: Whatever

#events.yml      
---
EventSerie11:
  date: 2013-01-01
  value: '124.4'
  serie: Serie1
EventSerie12:
  date: 2013-02-01
  value: '124.2'
  serie: Serie1

The problem is that when I load these fixtures by using rake db:fixtures:load, I get the wrong foreing keys for the event objects:

$ rails c
Loading development environment (Rails 4.1.0)
2.1.1 :001 > Serie.first.id
  Serie Load (0.2ms)  SELECT  "series".* FROM "series"   ORDER BY "series"."id" ASC LIMIT 1
 => 10
2.1.1 :002 > Serie.first.events.count
  Serie Load (0.3ms)  SELECT  "series".* FROM "series"   ORDER BY "series"."id" ASC LIMIT 1
   (0.2ms)  SELECT COUNT(*) FROM "events"  WHERE "events"."serie_id" = ?  [["serie_id", 10]]
 => 0  
2.1.1 :003 > Event.first.serie
  Evento Load (0.2ms)  SELECT  "events".* FROM "events"   ORDER BY "events"."id" ASC LIMIT 1
  Serie Load (0.3ms)  SELECT  "series".* FROM "series"  WHERE "series"."id" = ? LIMIT 1  [["id", 627975337]]
 => nil 
2.1.1 :004 > Evento.first.serie_id
  Evento Load (0.4ms)  SELECT  "eventos".* FROM "eventos"   ORDER BY "eventos"."id" ASC LIMIT 1
 => 627975337 

So you see that all fixtures are loading, but the Event records are being assigned an incorrect serie_id foreign key (and since I'm using sqlite for development there are no constraint checks). As far as I can tell, each time I reset the database and load the fixtures, the Serie record gets a new id, but the serie_id field of each Event record is always set to 627975337.

I read here that you can specify the load order for your fixtures; however adding the line

ENV["FIXTURES"] ||= "series,events" 

to my environment.rb file didn't work, nor did running

rake db:fixtures:load FIXTURES=series,events

Any ideas?

like image 635
ailnlv Avatar asked May 06 '14 19:05

ailnlv


1 Answers

I think rails is getting in a muddle with your class/fixtures name for series. It tries to look for a model class named Series because it struggles to singularize your plural name. (Series being a word in english where the plural is the same as the singular).

I strongly suspect that the Serie instance in your database is nothing to do with your fixture load at all and is instead an instance that has been created via another method.

The serie_id used in your events fixtures is correct. The id that is used is calculated using:

> ActiveRecord::FixtureSet.identify(:Serie1)
=> 627975337

which you can see is the same as the value used in your fixtures.

So, a solution, you can either get into the bowels of active record and override the rake task that loads the fixtures - or you can define your singular/plural versions of "serie"/"series" to be what you want rather than what rails is guessing. In config/application.rb or an initializer you can add:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'serie', 'series'
end
like image 116
Shadwell Avatar answered Oct 14 '22 04:10

Shadwell