83946


# 前提

Railsでモデルの関係づけをしていて躓いてしまいましたので、ご助言よろしくお願いします。

以下のようなリレーションを実装しようとしています。

[![実現したいリレーション](https://i.stack.imgur.com/rzm6Q.png)](https://i.stack.imgur.com/rzm6Q.png)

  * `User`は必ず`好きな食べ物`と`嫌いな食べ物`をひとつずつ持つ
  * `Food`は主キーに`string型`の`food_id`を持つ
  * `Food`は複数のユーザから持たれる可能性がある

ような状況を考えています。

# 質問

以上のようなときの、マイグレーションの定義とモデル.rbの定義の仕方を知りたいです。

# 現状できていること

以下のように`Userテーブル`から`Foodテーブル`に対して、単一のリレーションを張ることはできました。

[![じつげんした](https://i.stack.imgur.com/dWflf.png)](https://i.stack.imgur.com/dWflf.png)

ただ、別名でのリレーションや複数のリレーションを共通のテーブルに対して張る方が分かりません。

## 現状の実装

単一の場合の以下のようにして実装可能でした。  
これを改造したりして、目的のことをできるのかなとは思うのですが、思いつきません。

[code]

    ###### マイグレーション
    # db/migrate/20211203123059_create_foods.rb
    class CreateFoods < ActiveRecord::Migration[6.1]
      def change
        create_table :foods, id: false do |t|
          t.string :food_id, null: false, primary_key: true
          t.string :name
        end
      end
    end
    
    # db/migrate/20211203123112_create_users.rb
    class CreateUsers < ActiveRecord::Migration[6.1]
      def change
        create_table :users do |t|
          t.string :name
          t.references :food, type: :string
        end
        add_foreign_key :users, :foods, column: :food_id , primary_key: :food_id
      end
    end
    
    #### モデル定義
    # app/models/food.rb
    class Food < ApplicationRecord
        self.primary_key = :food_id
        has_many :users
    end
    
    # app/models/user.rb
    class User < ApplicationRecord
      belongs_to :food
    end
    
[/code]

rails コンソールで以下が可能でした。

[code]

    # 登録
    > food1 = Food.create(name: 'orange', food_id: 'fruit-01')
    > food2 = Food.create(name: 'hamburger', food_id: 'meal-01')
    > user1 = User.new(id: 1, name: 'us01')
    > user1.food = food1
    > user1.save
    
    # 確認
    > User.first
      User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
    => #<User:0x000055730b2b7568 id: 2, name: "us01", food_id: "fruit-01">
    
[/code]


CC BY-SA 4.0
2021-12-03T13:37:24.680
83944
2021-12-03T15:26:59.573
2021-12-03T13:45:03.917
47477
47477
question
ruby-on-rails ruby rails-activerecord
Rails でテーブル内の複数カラムから共通のテーブルを別名でリレーションする方法が分からない


references 型で foreign_key に to_table を指定します

[code]

    #  db/migrate/20211203144103_create_foods.rb
    class CreateFoods < ActiveRecord::Migration[6.1]
      def change
        create_table :foods do |t|
          t.string :name
          t.timestamps
        end
      end
    end
    
[/code]

[code]

    #  db/migrate/20211203145246_create_users.rb
    class CreateUsers < ActiveRecord::Migration[6.1]
      def change
        create_table :users do |t|
          t.string :name
          t.references :favorite_food, foreign_key: { to_table: 'foods' }
          t.references :disliked_food, foreign_key: { to_table: 'foods' }
          t.timestamps
        end
      end
    end
    
[/code]

[code]

    #  app/models/user.rb
    class User < ApplicationRecord
      belongs_to :favorite_food, class_name: "Food", optional: true
      belongs_to :disliked_food, class_name: "Food", optional: true
    end
    
[/code]

[code]

    #  app/models/food.rb
    class Food < ApplicationRecord
      has_many :lovers, class_name: "User", foreign_key: "favorite_food_id"
      has_many :haters, class_name: "User", foreign_key: "disliked_food_id"
    end
    
[/code]


CC BY-SA 4.0
2021-12-03T15:26:59.573
83946
2021-12-03T15:26:59.573
292
83944
answer