34

如何使用引用同一个表的两个字段创建迁移?我有表 A 和图像。A.image1_id 将引用图像,A.image2_id 也将引用图像。只有2张图片,不多。如果我使用

class AddFields < ActiveRecord::Migration
   def change
    change_table(:ticket) do |t|
        t.references :image1_id
        t.references :image2_id
    end
  end
end

我认为这不会起作用,因为它会在末尾添加另一个 _id 并且可能不知道使用“图像”模型。我也想过

change_table(:ticket) do |t|
    t.references :image

但是,我该如何添加其中的两个呢?我也想过加

create_table :images do |t|
  t.belongs_to :ticket
  t.string :file

但是我只想要 2 个,而不是很多,而且这似乎不允许从票证中获取图像,例如ticket.image1or ticket.image2

根据我能找到的所有文档http://apidock.com/rails/v3.2.8/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table,t.references似乎也没有接受任何参数。

change_table(:suppliers) do |t|
  t.references :company
end
4

2 回答 2

45

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.

于 2013-02-14T05:18:27.437 回答
22

在 Rails 5.1 或更高版本中,您可以这样做:

移民

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

这将创建字段image1_id,并对表image2_id进行数据库级引用images

楷模

就像罗斯塔的回答一样

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

工厂机器人

如果您使用 FactoryBot,那么您的工厂可能看起来像这样:

FactoryBot.define do
  factory :ticket do
    association :image1, factory: :image
    association :image2, factory: :image
  end
end
于 2019-08-02T08:02:57.780 回答