0

When testing some things in the rails console I noticed this strange thing happening when I call a record and attempt to save it.

2.1.5 :026 > p = WorkOrder.first
WorkOrder Load (0.4ms)  SELECT  `work_orders`.* FROM `work_orders`   ORDER BY `work_orders`.`id` ASC LIMIT 1
=> #<WorkOrder id: 3, client_id: 4, created_at: "2015-06-17 17:12:07", updated_at: "2015-06-17 17:12:07", dueDate: "2015-07-17", number: "0221506-003", project_type_id: 2, monthlySequenceNumber: "003", projectDescription: "Project", status_id: 1, labels_id: nil> 
2.1.5 :027 > p.save
(0.2ms)  BEGIN
ProjectType Load (0.5ms)  SELECT  `project_types`.* FROM `project_types`  WHERE `project_types`.`id` = 2 LIMIT 1
(0.1ms)  COMMIT
=> true 

Why does it appear to be performing a select on the associated object? Also the records are not being committed back to the database. What am I missing that causes it to behave in such a seemingly strange way?

EDIT: What prompted me to start try to save records that I pulled from the database was that I had an identical issue doing something like

p.delete

and then

p.save

which would return true, but would only perform that strange select on the Project Type

Soviet_Jesus
  • 31
  • 10

2 Answers2

0

Why does it appear to be performing a select on the associated object?

This is possibly caused by validation code or callbacks in the WorkOrder model.

Also the records are not being committed back to the database. What am I missing that causes it to behave in such a seemingly strange way?

You have not modified the record, so the only field I would expect to be updated would be updated_at. It is possible to disable the timestamp feature for ActiveRecord. Have you done that? (reference Is there a way to avoid automatically updating Rails timestamp fields?)

UPDATE

The same thing happens when I tested p.delete followed by p.save, the result is true. This could be a bug, but I have not researched it enough to determine that yet.

After a quick look in the ActiveRecord source I think that what happens is that since you have first deleted your record (p), 0 rows in the database match that record's id (p.id). That means that when you run p.save 0 rows get updated (update instead of insert because the record is considered persisted). That number of rows gets compared with false here so that 0 != false returns true.

Community
  • 1
  • 1
Wizard of Ogz
  • 12,543
  • 2
  • 41
  • 43
  • I think I chose a bad example, but what was also happening was I would do something like p.delete, which removed it from the database, but then p.save wouldn't put it back in even though it returned true. It would only perform the select on the associated table like in my example. Is it likely that something in my validations is causing it to "short out" so to speak? – Soviet_Jesus Jun 18 '15 at 21:24
  • Ah, that is strange behavior. I dug a little deeper into the issue. See my updated answer for the details. – Wizard of Ogz Jun 19 '15 at 13:54
  • So if I'm reading your link right, rails is determining that my record is persisted and thus attempting to update a non-existent record? I was eventually able to stick the record back in by the rather roundabout WorkOrder.create(p.attributes), but that seems a tad silly. Though I suppose the notion of deleting and undeleting a record is a tad silly to begin with. Also on a related note after deletion p.persisted? returns false, which I'm fairly sure is expected. – Soviet_Jesus Jun 19 '15 at 14:49
  • Yes, I think that is it. I should have said "considered not a new record" instead of "considered persisted". After `x.destroy` both persisted? and new_record? return false. `x.persisted? #=> false`, `x.new_record? #=> false` – Wizard of Ogz Jun 19 '15 at 17:03
0

Due to the fact that you haven't changed any attribute, just try p.touch instead of p.save. This should save the record anyway.

Ionic
  • 3,884
  • 1
  • 12
  • 33