Anthony To
Anthony To

Reputation: 2303

ActiveRecord shows the same record with different attributes depending on how it is referenced

I'm debugging some of my Rspec tests and have run into something very strange in my DB. Basically I have two models, Invited and Group. Invited belongs_to a Group.

So I have two different variables that are referencing the same Invited record. Theoretically, those two variables should belong_to the same Group record. And indeed, all the ID's in my records all match, except for a single attribute in the Group record is mismatched. Here is some console output demo:

[54] pry> invited
=> #<Invited id: 1, email: "[email protected]", confirmation_token: "3460b1f237f0e7cb97eb3a325bd79cbdb0696405", subscribed: false, groups_training_level_id: 1, group_id: 1, created_at: "2015-12-20 01:47:03", updated_at: "2015-12-20 01:47:03">
[55] pry> inv
=> #<Invited id: 1, email: "[email protected]", confirmation_token: "3460b1f237f0e7cb97eb3a325bd79cbdb0696405", subscribed: false, groups_training_level_id: 1, group_id: 1, created_at: "2015-12-20 01:47:03", updated_at: "2015-12-20 01:47:03">
[56] pry> Group.all
=> [#<Group id: 1, name: "Brandi", start_at: "2015-12-19 05:00:00", expire_at: "2015-12-27 04:59:59", program_id: 3, speciality_id: 3, created_at: "2015-12-20 01:47:02", updated_at: "2015-12-20 01:47:02">]
[57] pry> invited.group
=> #<Group id: 1, name: "Brandi", start_at: "2015-12-19 05:00:00", expire_at: "2015-12-27 04:59:59", program_id: 2, speciality_id: 3, created_at: "2015-12-20 01:47:02", updated_at: "2015-12-20 01:47:02">
[58] pry> inv.group
=> #<Group id: 1, name: "Brandi", start_at: "2015-12-19 05:00:00", expire_at: "2015-12-27 04:59:59", program_id: 3, speciality_id: 3, created_at: "2015-12-20 01:47:02", updated_at: "2015-12-20 01:47:02">
[59] pry> Group.where(program_id: 2)
=> []

As you can see, invited and inv are both referencing the same record. Only one Group record exists, with id: 1. When I do invited.group and inv.group, the Group with the right id shows up, but the program_ids are different! I am perplexed by this, and I'm hoping someone can shed some light here. I am happy to provide more info, please do not hesitate to ask.

I am on Rails 3.2 and mysql2 (0.3.18).

Edit to include more info:

I can reproduce this consistently, although the steps are a bit complex. invited is generated by FactoryGirl:

let!(:invited) { FactoryGirl.create(:invited, email: sub.email, group: group) }

sub references a model that contains an email. inv is later retrieved using ActiveRecord like this:

inv = Invited.includes(group: :program).where(email: sub.email)[0]

Sure enough, Group.count returns 1.

Upvotes: 1

Views: 49

Answers (1)

froderik
froderik

Reputation: 4808

(It is a bit hard to answer this question without more information but I'll give it a go anyway.)

Clearly the program_id is different in inv and invited. The only way this could happen as far as I can tell is that some code is actually changing either the one in memory invited or the content in the database that later turn up as inv. The object you have in memory will have whatever content it had when you loaded it into memory plus whatever state you have changed on it since it was loaded. This will often be different from what is in the database.

I would have a look at invited right after it is created and also look for changes to group instances. Maybe you are changing a group reference somewhere in the test. Or you have some hooks that alters the model (a common source of frustration when it comes to rails).

Upvotes: 1

Related Questions