2017-10-12 26 views
1

Rails 5アプリケーションで次のような状況をコード化しようとしています。 私はこれらの2つのモデルがあります:2つのモデル間の複数の関連付け - Rails 5

class User < ApplicationRecord 
    has_many :mastered_games, class_name: 'Game', foreign_key: 'game_id' 
    has_and_belongs_to_many :played_games, class_name: 'Game', foreign_key: 'game_id' 
end 

class Game < ApplicationRecord 
    belongs_to :dungeon_master, class_name: 'User', foreign_key: 'user_id' 
    has_and_belongs_to_many :players, class_name: 'User', foreign_key: 'user_id' 
end 

本の一般的な考え方は、すべてのユーザーが、多くの演奏やゲームの習得、および任意のゲームがちょうど1人のユーザー(DungeonMaster)に属しており、多くのユーザーは、上の再生を持って持つことができるということですそれ(選手)。モデル名を使うのはおそらくもっと簡単だろうが、これははるかにレキシカルであり、おそらくお互いに衝突するだろう。

次のようになりための私の移行:これは私のために動作していないよういくつかの理由について

class CreateGames < ActiveRecord::Migration[5.1] 
    def change 
    create_table :games do |t| 
     t.integer :game_id 
     t.string :secret_key 
     t.belongs_to :dungeon_master, index: true 
     t.timestamps 
    end 
    end 
end 

class CreateUsers < ActiveRecord::Migration[5.1] 
    def change 
    create_table :users do |t| 
     t.integer :user_id 
     t.string :name 
     t.string :email 
     t.string :picture 
     t.string :provider 
     t.string :uid 
     t.timestamps 
    end 
    end 
end 

class CreateGamesUsersTable < ActiveRecord::Migration[5.1] 
    def change 
    create_join_table :games, :users do |t| 
     t.index :game_id 
     t.index :user_id 
    end 
    end 
end 

。例えば、私はそうのように、レールのコンソールにゲームにdungeon_masterを追加しようとすると:

u = User.new(name: 'Jon') 
g = Game.new() 
g.dungeon_master = u 

これはエラーActiveModel::MissingAttributeError: can't write unknown attribute user_idを返します。 また、私は次のようにゲームにユーザーを追加するとき、私は、多くの団体には多くの双方向性に問題を抱えている:ユーザーが追加された

g.players << u 

が、私はそのユーザーplayed_gamesにアクセスしようとすると、それゲームを返しません。私はおそらく何かが不足していますが、私は何が分かりません。 ご協力いただければ幸いです。

ありがとうございます!

答えて

0

あなたの指向性の一部が反転しています。いずれのモデルでもbelongs_toがあると、データベーステーブルに外部キーが送られます。今すぐgamesテーブルにgame_idの列があります。

create_table :games do |t| 
    t.references :dungeon_master 
    # other columns 
end 

create_table :users do |t| 
    # other columns 
end 

create_join_table(:games, :users) 

を次に、あなたのモデルは少し単純です:あなたが欲しいのはuser_iddungeon_master_id列(正直、それはだけではなく、モデルに手動で指定するデフォルトの外部キーの名前を使用する方がはるかに簡単だ)とgamesテーブルです:

class User < ApplicationRecord 
    has_many :mastered_games, class_name: 'Game', inverse_of: :dungeon_master 
    has_and_belongs_to_many :played_games, class_name: 'Game' 
end 

class Game < ApplicationRecord 
    belongs_to :dungeon_master, class_name: 'User', inverse_of: :mastered_games 
    has_and_belongs_to_many :players, class_name: 'User' 
end 

そして、あなたは以下と何ら支障がないはずです。

user = User.new(name: 'Jon') 
game = Game.new(dungeon_master: user) 
+0

おい、それは速かったし。 asnwerありがとう、それはすぐに私の問題を解決しませんでしたが、それは仕事のほとんどをしました。私はhas_many(Userモデルの場合)とbelongs_to(Gameモデルの場合)に外部キーを追加しました。 もう一度、非常に感謝! –

関連する問題