Sword 1.0b5 · A simple and friendly weblogging tool for academic environments created by Fingertips design & development.

 
 
 
 
 

Rails ActiveRecord bug

TrackBack link: http://blog.markjuh.net/markjuh/trackback/2005/7/29/rails_activerecord_bug

Published on 29 July 2005 at 16:43, updated at 16:48.

In category Rails.

Today I had to make sure a model couldn’t be saved if someone tried to update a certain field.

Reading in the API documentation I found the following:

If a before_* callback returns false, all the later callbacks and the associated action are cancelled.

So a before_update callback in my model would be the solution. I just had to make sure it would return false in the right cases.

Because of the last three months of test-driven development, I decided to write a test first. And to my surprise I could always save the model, even if my before_update callback would always return false. First I double-checked my test, but it was okay. Time to use yet another great tool in Rails: script/console.

It showed that even though the save method always returned true, it in fact did not save the model. So fortunately no problem with the before_update callback. This meant that there was no way avoiding it anymore… I would take my first dive into the ActiveRecord code.

After quite some time of searching back and forth through a couple of Ruby files, I found the problem:


def create_or_update
  if new_record? then create else update end
  true
end

And see here, it always returns true instead of the actual result from create or update. Why? Well, probably because there would be a problem in the create method:


def create
  self.id = connection.insert(
    "INSERT INTO #{self.class.table_name} " +
    "(#{quoted_column_names.join(', ')}) " +
    "VALUES(#{attributes_with_quotes.values.join(', ')})",
    "#{self.class.name} Create",
    self.class.primary_key, self.id, self.class.sequence_name
  )     

  @new_record = false 
end   

This create method returns the value of new_record (which is false), instead of the result of the query (self.id).

I’ve written a simple patch (see ticket #1861), which solves my problems and doesn’t introduce any new problems in my application. But again, it would be good to have a test for ActiveRecord. The problem is that I’m just not well-acquainted with ActiveRecord, so I have no idea where or how to incorporate the test. Any help with this would be greatly appreciated.

Comments

MarkusQ on 23 August 2005 at 03:45.

Thanks! You (and Google) answered my question before I’d even clearly formulated it. I was at the ??? stage, but now all is clear.

—MarkusQ

Mark van Eijk on 15 November 2005 at 16:15.

On a new note, this is not considered a bug. It has to do with the default semantics of the .save method. I will expand on this in a later post.

New comments are disabled for this post