The Rails default behaviour is that the column used to hold the foreign key on a model is the name of the association with the suffix _id
added. The :foreign_key
option lets you set the name of the foreign key directly. The associations between your Post
and Comment
model classes should look like this:
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
end
—Note that you don't need :class_name => "Post"
in your Comment
model. Rails already has that information. You should only be specifying :class_name
and :foreign_key
when you need to override the Rails' conventions.
You're correct that Rails maintains the foreign key relationships for you. You can enforce them in the database layer if you want by adding foreign key constraints.
rename_column :table, :old_column, :new_column
You'll probably want to create a separate migration to do this. (Rename FixColumnName
as you will.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Then edit the migration to do your will:
# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
def self.up
rename_column :table_name, :old_column, :new_column
end
def self.down
# rename back if you need or do something else or do nothing
end
end
For Rails 3.1 use:
While, the up
and down
methods still apply, Rails 3.1 receives a change
method that "knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate down method".
See "Active Record Migrations" for more information.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
If you happen to have a whole bunch of columns to rename, or something that would have required repeating the table name over and over again:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
You could use change_table
to keep things a little neater:
class FixColumnNames < ActiveRecord::Migration
def change
change_table :table_name do |t|
t.rename :old_column1, :new_column1
t.rename :old_column2, :new_column2
...
end
end
end
Then just db:migrate
as usual or however you go about your business.
For Rails 4:
While creating a Migration
for renaming a column, Rails 4 generates a change
method instead of up
and down
as mentioned in the above section. The generated change
method is:
$ > rails g migration ChangeColumnName
which will create a migration file similar to:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Best Answer
in rails 5.x you can add a foreign key to a table with a different name like this:
Inside a
create_table
block