I am testing a method on my group model. It relies on creating a few badgetypes through a factory.
Here is the code
it "add itself to badges with method add_to_badgetypes" do
badge = FactoryGirl.create(:badgetype)
old_badge_ids = badge.group_ids.split(",")
badge2 = FactoryGirl.create(:badgetype, :group_ids => "3,4,5")
group.add_to_badgetypes(badge.id, badge2.id)
expect( badge.group_ids ).to eq( old_badge_ids.push(group.id).join(",") )
end
‘
badge.group_ids’ is “200, 300” before, and should be “200,300,#{group.id}” after. When I’m tailing the log, I see this:
` Badgetype Load (0.5ms) SELECT group_ids FROM `badge_types` WHERE `badge_types`.`id` = 40 LIMIT 1
(0.2ms) SAVEPOINT active_record_1
(0.3ms) UPDATE `badge_types` SET `group_ids` = '200,300,15' WHERE `badge_types`.`id` IS NULL
(0.2ms) RELEASE SAVEPOINT active_record_1
Badgetype Load (0.4ms) SELECT group_ids FROM `badge_types` WHERE `badge_types`.`id` = 41 LIMIT 1
(0.1ms) SAVEPOINT active_record_1
(0.3ms) UPDATE `badge_types` SET `group_ids` = '3,4,5,15' WHERE `badge_types`.`id` IS NULL
(0.1ms) RELEASE SAVEPOINT active_record_1
(0.3ms) ROLLBACK
(0.1ms) BEGIN
`
So it is successfully updating the group_ids, but for some reason the test fails, and if I pp badge.group_ids I get the original value (200,300), and not the updated value.
I assume this has something to do with ‘SAVEAPOINT active_record_1’, then the UPDATE, and then RELEASE SAVEPOINT. If so, why?
How can I get this spec to pass, as it seems to all be messing up in the db, not the method.
Thanks
EDIT
Found out some more interesting information by playing around in the console. If I create a factory and assign it it one line:
g = FactoryGirl.create(:group)
and then run:
g.add_to_badgetype(1,2)
I get this SQL
1.9.3-p286 :080 > g.add_to_badgetypes(1, 2)
Badgetype Load (0.5ms) SELECT group_ids FROM `badge_types` WHERE `badge_types`.`id` = 1 LIMIT 1
(0.1ms) BEGIN
(0.2ms) UPDATE `badge_types` SET `group_ids` = 'test,8,9,10' WHERE `badge_types`.`id` IS NULL
(0.1ms) COMMIT
Badgetype Load (0.3ms) SELECT group_ids FROM `badge_types` WHERE `badge_types`.`id` = 2 LIMIT 1
(0.1ms) BEGIN
(0.2ms) UPDATE `badge_types` SET `group_ids` = '200,300,8,9,10' WHERE `badge_types`.`id` IS NULL
(0.1ms) COMMIT
=> [1, 2]
Notice the odd UPDATE statement “WHERE badge_types.id IS NULL”
If after I create the factory, I reassign it to a variable and then run the same command, it works find:
1.9.3-p286 :081 > g = Group.last
Group Load (0.5ms) SELECT `groups`.* FROM `groups` ORDER BY `groups`.`id` DESC LIMIT 1
=> #<Group id: 10, group_name: "Test Group", short_name: "test_group", enrollment: false, kiosk: false, landing: 0, ro_landing: 0>
1.9.3-p286 :082 > g.add_to_badgetypes(1, 2)
Badgetype Load (0.6ms) SELECT `badge_types`.* FROM `badge_types` WHERE `badge_types`.`id` = 1 LIMIT 1
(0.1ms) BEGIN
(0.4ms) UPDATE `badge_types` SET `group_ids` = 'test,8,9,10' WHERE `badge_types`.`id` = 1
(0.2ms) COMMIT
Badgetype Load (0.4ms) SELECT `badge_types`.* FROM `badge_types` WHERE `badge_types`.`id` = 2 LIMIT 1
(0.1ms) BEGIN
(0.4ms) UPDATE `badge_types` SET `group_ids` = '200,300,8,9,10' WHERE `badge_types`.`id` = 2
(0.2ms) COMMIT
=> [1, 2]
So apparently groups being a factory is causing the SQL update statement to look for ids of NULL.
Any ideas?
Aaaaaaand I figured it out.
I just needed to reload the variable “badgetype”
before the test for equality, I added
@badge.reload
et voila. Weird.