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.
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.
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.
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.
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.
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).
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 createid
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