David Unric
David Unric

Reputation: 7719

Rails update form issue?

can anybody explain the following strange behaviour of update form ?

Issue description:

  1. in an update form invalid value for :id is given like 42
  2. the validation helper handles the invalid input value (< 100) and passes a notification "Id must be greater than or equal to 100" and data are not updated
  3. the field for :id is replaced with some correct value like 123 and Update Post button is submitted again
  4. instead of form reception and updating the database, Rails throw an exception ActiveRecord::RecordNotFound in PostsController#show

    Couldn't find Post with id=42

What's going on here ? Why the expception and why the old value is passed again ?

Upvotes: 0

Views: 528

Answers (2)

Ahmad Sherif
Ahmad Sherif

Reputation: 6213

update_attributes method doesn't update primary keys nor read-only attributes. Even more, update_attributes uses id attribute in the WHERE condition in the update SQL statement, so if you changed the id attribute you'll end up updating a record which has this ID already (or no update at all if the id doesn't exist in the db).

As a workaround, you'll either have to write your update SQL statement yourself, or hit the database twice by creating a new record with the desired id (copying the old attributes and setting a new id) and deleting the old one.

That said, I agree with @MrDanA that updating primary keys is not a very good idea and I think you should think about another approach to your issue.

Upvotes: 0

MrDanA
MrDanA

Reputation: 11647

Well the problem is that in your controller you are doing this:

@post = Post.find(params[:id])

And you are passing in an ID of 42. So the controller goes and tries to find a Post object with an ID of 42. However, there is no Post with an ID of 42, so it throws an error. It never even gets to your update_attributes call, and never even goes to your validation.

You must either rescue from this error, or use the find_by_id method which will return nil if no record is found.

In addition though, I'm wondering, why are you letting your users enter in an ID by hand? They shouldn't know about that. Is this ID supposed to be different than a primary key? Consider adding a different column then, like identifier or key or something to make it less ambiguous if that's the case. Could run in to a lot of issues if you're trying to manipulate ID (which actually come to think of it may be allowed by Rails).

Upvotes: 1

Related Questions