I have a table called Contracts. Its current default primary key is the :id field that Rails automatically generates, which is an integer. I want to have a field called contractId that is a string type and use it as a primary key instead. What I want to know is:
Is this a best practice? Are there any potential issues with doing this?
How I would go about it
Ruby on Rails (RoR) likes to emphasise the concept of convention over configuration. Therefore, it seeks to minimialise the amount of configuration. So if you want contractId that is a string type then you can add one extra field in your table and use it wherever you want and let the Rails use id as primarykey.
Change PrimaryKey
Generate a new migration file name it "ChangePrimaryKey" (You can give any name).
class ChangePrimaryKey < ActiveRecord::Migration
def up
remove_column :table, :id # remove existing primary key
rename_column :table, :udid, :id # rename existing UDID column
execute "ALTER TABLE table ADD PRIMARY KEY (id);"
end
def down
# Remove the UDID primary key. Note this would differ based on your database
execute "ALTER TABLE table DROP CONSTRAINT table_pkey;"
rename_column :table, :id, :udid
add_column :table, :id, :primary_key
end
end
If you are creating a new table, your migration might look like this:
class AddTableWithDifferentPrimaryKey < ActiveRecord:Migration
def change
create_table :table, id: false do |t|
t.string :id, null: false
# other columns
t.timestamps
execute "ALTER TABLE table ADD PRIMARY KEY (id);"
end
end
end
Notice the id: false options you pass into the table — this asks Rails not to create a primary key column on your behalf.
Changes to Model
In the model, it is essential that you add the following line in order for Rails to programmatically find the column you intend to use as your primary key.
class Table < ActiveRecord::Base
self.primary_key = :id
# rest of span
end
I hope you can do rest of the things.
Don't change default id if you want to see Rails real Magics :)
As you may know, Rails supports changing the primary id column out of the box:
class Contract < ActiveRecord::Base
self.primary_key = "contractId"
end
Please note that even if the contractId column has a unique index, an index on a string column will always be a bit slower than an index in an integer column.
Furthermore, this is not the Rails way and might confuse other developers that work with this application. Especially building associations or routes are error-prone when your table has a non-standard primary key. IMHO that is a good reason to avoid using this technic as long as possible.
来源:https://stackoverflow.com/questions/23846090/rails-non-integer-primary-key