2017-10-12 93 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 

的這個總的想法是,任何用戶都可以有很多發揮和掌握遊戲,和任何給定的遊戲屬於只有一個用戶(地下城大師),並擁有衆多用戶玩它(玩家)。我知道使用模型名稱可能會更容易,但這更加的詞法,此外,這些關聯可能會相互衝突。

我現在遷移是這樣的:

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列。你想要的是一個games表與user_iddungeon_master_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) 

你的模型是稍微簡單:

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

夥計,那是快。感謝您的幫助,它並沒有立即解決我的問題,但它完成了大部分工作。我已經爲has_many(對於用戶模型)和belongs_to(對於遊戲模型)添加了外鍵,並且它至少一次堅持模型,而不僅僅是在控制檯上玩耍。 再一次,非常感謝! –