How to assign a non-auto ID?

You can use the existing key field and key value. I'm doing this in apps being rewritten, as well as in databases that are being shared by Rails & other platforms. I have found no need so far to insist on the autoinc field.

In your model, if the field name is not "id," you can declare the keyfield like this:

   self.primary_key = "rcrd_id" # or whatever the name is

When you declare associations, you can use the :foreign_key => 'xxx' option in :has_one,:has_many etc to define a field name that does not follow Rails' convention.

The only tricky part is when *reading the key value, you can specify the field as my_model.rcrd_id (as expected), but when *writing the value, you still have to use the Rails default of my_model.id (presumably because .id is a manually written accessor method), so the name doesn't change even when the field name does.

Next, add a method to each ActiveRecord model similar to this one to create the key value for when new records are created:

   def before_create      self.id = 20.random_id    end

That .random_id is custom extension I use, so do whatever it is you normally do to generate your keyfield values.

Is that the kind of info you're looking for?

When you create your DBs, simply do not make the ID field autoinc (make it integer, etc like it was going to be an autoinc though). Then after the importing is done, turn autoinc on, and MySQL will automatically pick up with the next highest number for new records.

Hi Sam,

ActiveRecord always protect it's PK from modifying ... One way to achieve your goal is to create a temp model use some other column as PK:

create_table products, :primary_key => :temp_id do |t|   t.column :temp_id, :integer   #add other stuff ... end

Then you can set&save id attribute to any value you want in Product. After you migration, you can remove the fake id column and modify your create_table back to normal.

Another approach is ... modifying the Rails source yourself, have a look on attributes_from_column_definition method in ActiveRecord::Base. We'll love opensource :slight_smile:

I don't know whether there's more clever ways ... Thanks, Jan

I'm still confused about your situation. If you have an existing database that you want to copy & modify, do just that. Use MYSQL to copy the database, use rails to modify things after that. The only issue would be if you were renaming tables. http://dev.mysql.com/doc/refman/6.0/en/mysqldump.html

I suspect that the output is hackable in the table name space.

Maybe it's a matter of word choice? It sounds like you are doing a conversion, not a simple migration.

Phillip

If you assign the id 'manually', it will be honored, if possible.

mycopy = Model.new(hash_of_old_attributes) { |m| m.id = oldid } # .. apply complex rules ... mycopy.save

Note that you can't have :id in the hash_of_old_attributes (well, it will be ignored if present).

-Rob

(of course, you're on the forum and may never see this message...)

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com