# How to change the primary key value of a table

**URL:** <https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769>\
**Category:** Rails\
**Created:** [June 18, 2008, 12:01pm UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769 "2008-06-18T12:01:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 18, 2008, 12:01pm UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/1 "2008-06-18T12:01:05Z")

</div>

Hello,

```
I am having problem changing the primary key value of a table

```

using active record. I want to change the id of OriginalName from 2 to  
6.

orders table:

±—±------------------±---------------------------------  
±--------------------------------±---------+  
| id | name | address |  
email | pay\_type |  
±—±------------------±---------------------------------  
±--------------------------------±---------+  
| 1 | Reginald | 288 Escolta |  
removed\_email\_address@domain.invalid | cc |  
| 2 | OriginalName | 3421 unkonwn address | removed\_email\_address@domain.invalid |  
po |  
| 3 | Third Eye | 3421 unkonwn address | removed\_email\_address@domain.invalid  
| po |  
±—±-------------------±--------------------------------  
±--------------------------------±---------+

What I did was to type the following on ruby script/console:

> > order=Order.find(2)

```
   => #<Order:0x4710184 @attributes={"name"=>"OriginalName",

```

“id”=\>“2”, “pay\_type”=  
\>“po”, “address”=\>“3421 unkonwn address”,  
“email”=\>“removed\_email\_address@domain.invalid”}\>

> > order.id

```
   => 2

```

> > order.id=6

```
   => 6

```

> > order.save

```
   => true

```

Although it displays a true message, there seems to be an error.

> > order  
> > =\> #\<Order:0x4709500 @errors=#\<ActiveRecord::Errors:0x4705cac  
> > @errors={}, @base=  
> > #\<Order:0x4709500 …\>\>, @new\_record\_before\_save=nil,  
> > @attributes={“name”=\>“Orig  
> > inalName”, “id”=\>6, “pay\_type”=\>“po”, “address”=\>“3421 unkonwn  
> > address”, “email”  
> > =\>“removed\_email\_address@domain.invalid”}\>

Moreover, when I queried the orders table using mysql, by typing  
“select \* from orders”, I don’t see any changes.

P.S. I’m using Rails 1.2.2 and MySQL 5.0.27

---

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 18, 2008, 12:36pm UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/2 "2008-06-18T12:36:50Z")

</div>

On 18 Jun 2008, at 10:59, soa\_dias wrote:

> Hello,
> 
> I am having problem changing the primary key value of a table  
> using active record. I want to change the id of OriginalName from 2 to  
> 6.

Rails won’t do that for you like that. Order.update\_all would probably  
handle it. (maybe Order.update too)

Fred

---

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 18, 2008, 4:21pm UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/3 "2008-06-18T16:21:06Z")

</div>

I think I might have the answer.

I believe the problem you are having is “when” you are changing the ID  
value. I had to deal not long ago with the same problems you’re  
facing.

In order to make it work I had to add a ‘before\_save’ method in the  
model:

def before\_save  
self.id = new\_value\_here  
end

AR will disregard the changes you make to the ID value, probably  
because it needs the original one for validations, etc. However, when  
it is ready to save the data to the table (and the ‘before\_save’  
method can be used) it does not need the ID any longer and is free for  
you to change it.

I hope this helps.

---

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 19, 2008, 5:19am UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/4 "2008-06-19T05:19:52Z")

</div>

Thanks for your input, but I couldn’t get your method to work, perhaps  
I was doing it wrong. I added the following to the Order model:

def before\_save(new\_value)  
self.id = new\_value  
end

Then, I fired up script/console. typed the following:  
order = Order.find(2)  
order.before\_save(6)  
order.save

After which an error would occur:

ArgumentError: wrong number of arguments (0 for 1)  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/callbacks.rb:348:in `before_save' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.2/lib /active_record/callbacks.rb:348:in`send’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/callbacks.rb:348:in `callback' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.2/lib /active_record/callbacks.rb:241:in`create\_or\_update’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/base.rb:1552:in `save_without_validation!' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.2/lib /active_record/validations.rb:762:in`save\_without\_transactions!’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/transactions.rb:133:in `save!' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.2/lib /active_record/connection_adapters/abstract/database_statements.rb: 59:in`transa  
ction’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/transactions.rb:95:in `transaction' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.2/lib /active_record/transactions.rb:121:in`transaction’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.2/lib  
/active\_record/transactions.rb:133:in `save!’  
from (irb):20

---

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 19, 2008, 5:08am UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/5 "2008-06-19T05:08:45Z")

</div>

Excellent. Order.update\_all allowed me to change the primary key  
value, thanks a lot. Order.update doesn’t work though, but that’s  
alright 🙂

On Jun 18, 6:33 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![soa\_dias](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bc8723/32.png) [@soa\_dias](https://www.ruby-forum.com/u/soa_dias)\
**Post date:** [June 19, 2008, 2:42pm UTC](https://www.ruby-forum.com/t/how-to-change-the-primary-key-value-of-a-table/140769/6 "2008-06-19T14:42:58Z")

</div>

Hello again.

The reason why the method would not work is because the method is a  
‘callback’ method. I don’t believe it accepts parameters.

A callback method is automatically called by Rails when you call the  
‘save’ method (order.save in this case). This callback method, if  
declared, is called for you by Rails before the record is actually  
saved to the DB:

you do:  
order.save

Rails does:  
order.before\_save  
then it saves the record

You would need to have a way of knowing the new value for ID from  
within before\_save, like storing it in an instance variable before you  
invoke order.save:

in your code:  
order.new\_value = 6  
order.save

def before\_save  
self.id = self.new\_value  
end

Although you already got the problem solved I would still try this. It  
might help in the future. Good luck.

Pepe
