Assigning Non-Sequential IDs in Rails
May 8th, 2008 | Published in Rails | 1 Comment
Before I forget this, I have to write it down, or next time I’ll be bugging my co-workers for the answer. Let’s say you’ve got a table in your database that has a (gasp!) non-sequential ID. Non-numeric, even (horrors!). And you want to build a form to input records, including a specific ID. Passing the handy params hash in full to an Object.create method call doesn’t work; ID is protected from mass-assignment even if you try to expose it via attr_accessible.
So instead of calling create, call Object.new and pass in the individual params except the ID. Then, on the next line, assign ID and then call save. Voila.
In action, then:
@person = Person.new(:first_name => params["person"]["first_name"], :last_name => params["person"]["last_name"])
@person.id = params["person"]["id"]
@person.save
Not that I recommend this for external apps, mind you. But it might come in handy in some circumstances.
Update: Aron suggested that this could be done without passing individual params items, and he’s right. You’d just have to pull out the ID first and assign it temporarily, then pass the entire params["person"] hash in our example to the create call and finally add the ID element back before saving.
May 17th, 2008 at 4:34 am (#)
No reason you couldn’t drop the params hash in there and then do the manual assign:
@person = Person.new(params["person"])
@person.id = params["person"]["id"]
@person.save
OR… you can have the form call your ID param something else, like params["person"]["legacy_id"] and then define :legacy_id= for person:
class Person < ActiveRecord::Base
def legacy_id=(v)
self.id = v
end
# for consistency
def legacy_id
self.id
end
end
@person = Person.new(params["person"])
@person.save
Plenty of ways to hit the same solution.