Reputation: 933
I've just inherited a blog platform that uses Rails 3.2 (!!), and I'm looking to add some functionality. I have two models, Article
and Issue
, which I'd like to associate such that any Issue
has_many :articles
and and any Article
belongs_to :issue
.
I've looked into using the gem foreigner
to help with this, but I'm wondering if there's a way to do this without adding more gems. I've looked around SO and seen some conflicting stuff. This SO post seems to only apply to Rails 4, which I guess automatically generates this sort of migration.
Can I do this manually by migrating to create appropriate integer fields in both schemas, and then putting the has_many
and belong_to
statements in the models?
Thanks so much!
Upvotes: 0
Views: 1946
Reputation: 10420
This is the snippet that I wrote to add multiple foreign keys in Rails 3.2
class ChangeAdminUsersEmployee < ActiveRecord::Migration
def up
ActiveRecord::Base.transaction do
tables = %i[admin_users]
reference = 'employee'
tables.each do |table|
p sql = <<-SQL
ALTER TABLE `#{table}`
ADD CONSTRAINT `#{table}_#{reference}_fk`
FOREIGN KEY (`#{reference}_id`) REFERENCES `#{reference}s`(`id`);
SQL
p ActiveRecord::Base.connection.execute(sql)
puts "===="
end
end
end
def down
raise NotImplementedError
end
end
Upvotes: 2
Reputation: 458
That's exactly what you should do: generate a migration for Article that adds the issue_id column:
$ rails g migration AddIssueToArticle issue:references
That'll generate a migration that will look like this, which will add the issue_id column and create an index:
class AddIssueToArticle < ActiveRecord::Migration
def change
add_reference :articles, :issue, index: true
end
end
$ rails g migration AddIssueIdToArticle issue_id:integer
Edit the generated migration and add an index:
class AddIssueIdToArticle < ActiveRecord::Migration
def change
add_column :articles, :issue_id, :integer
add_index :articles, :issue_id
end
end
Run the migration:
$ rake db:migrate
$ rake db:test:prepare
And then add the relationship to the Article and Issue classes:
# ./app/models/article.rb
class Article
belongs_to :issue
# ... the rest of the class
end
# ./app/models/issue.rb
class Issue
has_many :articles
# ... the rest of the class
end
If your classes are namespaced or the integer column is a different name, then you'll need to add more data to the belongs_to
and has_many
method arguments.
See the docs for 4.0 (and 3.2) for more about generating migrations.
Upvotes: 0