web-dev-qa-db-ja.com

1つのテーブルで同じモデルへの複数の参照を含む移行を追加するにはどうすればよいですか? Ruby / Rails

同じテーブルを参照する2つのフィールドを含む移行を作成するにはどうすればよいですか?テーブル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

しかし、どうすればそれらの2つを追加できますか?追加することも考えました

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

しかし、私は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
29
Chloe

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

このブログの投稿 同じテーブルで複数の関連付けを作成する は、さらに詳しく説明しています。

35
rossta

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_idimage2_idが作成され、データベースレベルでimagesテーブルが参照されます。

モデル

rossta's asnwer のように

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を使用する場合、ファクトリは次のようになります。

FactoryBot.define do
  factory :ticket do
    association :image1, factory: :image
    association :image2, factory: :image
  end
end
2
Toby 1 Kenobi