mostsquares
mostsquares

Reputation: 933

Adding foreign keys in Rails 3.2

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

Answers (2)

ecoologic
ecoologic

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

Jen
Jen

Reputation: 458

EDIT: Rails 4

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 3.2

$ 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

Both versions:

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

Related Questions