如何在一个表中添加对同一模型的多个引用的迁移?的Ruby/Rails

Chl*_*loe 27 ruby ruby-on-rails rails-migrations rails-activerecord

如何使用引用同一个表的两个字段创建迁移?我有表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
Run Code Online (Sandbox Code Playgroud)

我认为这不会起作用,因为它会在最后添加另一个_id,并且可能不会知道使用'image'模型.我也想过

change_table(:ticket) do |t|
    t.references :image
Run Code Online (Sandbox Code Playgroud)

但是,我该如何添加其中两个呢?我还考虑过添加

create_table :images do |t|
  t.belongs_to :ticket
  t.string :file
Run Code Online (Sandbox Code Playgroud)

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

根据这个文档http://apidock.com/rails/v3.2.8/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table这是我能找到的全部内容,t.references似乎也没有任何参数.

change_table(:suppliers) do |t|
  t.references :company
end
Run Code Online (Sandbox Code Playgroud)

ros*_*sta 35

您可以使用add_column迁移中的方法简单地执行此操作,并在类中设置正确的关联:

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
Run Code Online (Sandbox Code Playgroud)

本博文" 使用相同表创建多个关联"更详细.

  • 对,`t.references:x`只是`t.column:x_id,:integer`或`t.integer:x_id`的简写. (4认同)
  • 哇`belongs_to`和`has_one`令人困惑.听起来倒退了.故障单"引用"图像,图像"属于"故障单. (2认同)

Tob*_*obi 5

在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
Run Code Online (Sandbox Code Playgroud)

这将创建字段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
Run Code Online (Sandbox Code Playgroud)

工厂启动

如果使用FactoryBot,则工厂可能看起来像这样:

FactoryBot.define do
  factory :ticket do
    association :image1, factory: :image
    association :image2, factory: :image
  end
end
Run Code Online (Sandbox Code Playgroud)