Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the behaviour of create_join_table of ActiveRecord::Migration?

I've discovered a nice way to generate join tables for my HABTM relationships in my Rails app.

rails g migration CreateJoinTable table1 table2

This generates an ActiveRecord::Migration that employs the method create_join_table

I'm wondering what this wonderful mysterious method does. I guess it makes a table (probably without an id field) that has a column for table1 foreign key and a column for table2 foreign key, but does the table have any other features?. My habit for join tables has always been to add a unique index across both those columns so that a relationship between a record in table1 and a record in table2 cannot be entered twice.

My question boils down to: If I use create_join_table do I need to keep adding that unique index, or does this method do that for me (I think it should)?

The documentation I usually look at doesn't go into this sort of detail.

like image 942
Toby 1 Kenobi Avatar asked Aug 25 '15 10:08

Toby 1 Kenobi


People also ask

What does Rails DB Migrate do?

A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.

What is ActiveRecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

How does Rails know which migration to run?

Rails uses this timestamp to determine which migration should be run and in what order, so if you're copying a migration from another application or generate a file yourself, be aware of its position in the order. This generator can do much more than append a timestamp to the file name.

How do I migrate a database in Ruby on Rails?

Go to db/migrate subdirectory of your application and edit each file one by one using any simple text editor. The ID column will be created automatically, so don't do it here as well. The method self. up is used when migrating to a new version, self.


2 Answers

Called without any block, create_join_table just creates a table with two foreign keys referring to the two joined tables.

However, you can actually pass a block when you call the method to do any additional operations (say, adding indexes for example). From the Rails doc:

create_join_table :products, :categories do |t|
  t.index :product_id
  t.index :category_id
end

Have a look at create_join_table documentation.

You can check the create_join_table code at the bottom (click on Source: show).

like image 146
Yanis Vieilly Avatar answered Oct 25 '22 21:10

Yanis Vieilly


SchemaStatements#create_join_table() only creates join table without any fancy indexes etc,... So if you wish to use uniqueness constraint on two fields you have to do something like this:

class CreateJoinTable < ActiveRecord::Migration
  def change
    create_join_table :posts, :users do |t|
      t.integer :post_id, index: true
      t.integer :user_id, index: true
      t.index [:post_id, :user_id], name: 'post_user_un', unique: true
    end
  end
end

Please also note that create_join_table by default does NOT create id field.

like image 40
Oto Brglez Avatar answered Oct 25 '22 20:10

Oto Brglez