Reputation: 26284
How do I create a migration with two fields that reference the same table? I have tables A, and image. A.image1_id will reference image, and A.image2_id will reference image also. There are only 2 images, not many. If I use
class AddFields < ActiveRecord::Migration
def change
change_table(:ticket) do |t|
t.references :image1_id
t.references :image2_id
end
end
end
I don't think that will work because it will add another _id to the end and probably won't know to use the 'image' model. I also thought about
change_table(:ticket) do |t|
t.references :image
But then how do I add two of those? I also thought about adding
create_table :images do |t|
t.belongs_to :ticket
t.string :file
But I only want 2, not many, and this doesn't appear to allow getting to the image from the ticket, like ticket.image1
or ticket.image2
.
According to this documentation http://apidock.com/rails/v3.2.8/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table which is all I could find, t.references doesn't appear to take any arguments either.
change_table(:suppliers) do |t|
t.references :company
end
Upvotes: 38
Views: 23975
Reputation: 5035
In Rails 5.1 or greater you can do it like this:
class AddFields < ActiveRecord::Migration
def change
change_table(:tickets) do |t|
t.references :image1, foreign_key: { to_table: 'images' }
t.references :image2, foreign_key: { to_table: 'images' }
end
end
end
This will create the fields image1_id
, and image2_id
and make the database level references to the images
table
as in rossta's asnwer
class Ticket < ActiveRecord::Base
belongs_to :image1, class_name: "Image"
belongs_to :image2, class_name: "Image"
end
class Image < ActiveRecord::Base
has_many :primary_tickets, class_name: "Ticket", foreign_key: "image1_id"
has_many :secondary_tickets, class_name: "Ticket", foreign_key: "image2_id"
end
If you uses FactoryBot then your factory might look something like this:
FactoryBot.define do
factory :ticket do
association :image1, factory: :image
association :image2, factory: :image
end
end
Upvotes: 30
Reputation: 11494
You can do this simply with the add_column
method in your migrations and set up the proper associations in your classes:
class AddFields < ActiveRecord::Migration
def change
add_column :tickets, :image_1_id, :integer
add_column :tickets, :image_2_id, :integer
end
end
class Ticket < ActiveRecord::Base
belongs_to :image_1, :class_name => "Image"
belongs_to :image_2, :class_name => "Image"
end
class Image < ActiveRecord::Base
has_many :primary_tickets, :class_name => "Ticket", :foreign_key => "image_1_id"
has_many :secondary_tickets, :class_name => "Ticket", :foreign_key => "image_2_id"
end
This blog post, Creating Multiple Associations with the Same Table, goes into more detail.
Upvotes: 45