Quick question: How to specify a collation for a specific column when creating a model with rails?
I haven't found any option in the rails API doc but I think it's very important to explicit declare a collation for some attributes.
Let's say that the default collation is utf8_unicode_ci
. But when creating an Users model the password field's collation should be utf8_bin
.
So, when using rails like this
rails g model Users username:string password:string
you can't specify password to use utf8_bin
collation.
Any way to do it?
EDIT: The generated SQL should be something like this:
CREATE TABLE `user` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique ID',
`username` VARCHAR(32) NOT NULL COMMENT 'Nick/username',
`password` VARCHAR(32) COLLATE utf8mb4_bin COMMENT 'Encoded password',
PRIMARY KEY(`id`),
INDEX(`username`)
);
I don't care if you can't do it directly via a command and you have to modify the db/timestamp_create_users.rb
file. But the point is being able to use the rails migrations.
You can set the collation by adding the T-SQL COLLATE clause to the CREATE TABLE and ALTER TABLE statements. When you use those statements, you define the column and its properties, including any collation settings.
The table collation is the same as the database collation, except if left blank, it will use the database as its default, then connection-specific, and then finally the server's collation.
When you already have users and uploads tables and wish to add a new relationship between them. Then, run the migration using rake db:migrate . This migration will take care of adding a new column named user_id to uploads table (referencing id column in users table), PLUS it will also add an index on the new column.
Sadly it seems that rails does not provide any high level way to set column-level collation so you have to fall back to SQL at least a little. Here's how I did it:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :password
end
reversible do |dir|
dir.up {
change_column :users, :password, "VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin"
}
end
end
end
The reversible
block is there just to enable rollbacks because rails would not know how to revert change_column
without the original value.
Then you can check the collation on the mysql cli with:
SHOW TABLE STATUS;
you should see your default collation there - probably utf8_unicode_ci. Then do:
SHOW FULL COLUMNS FROM users;
And there you should see utf8_bin at the password field.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With