【问题标题】:Proper way to set up models and relationships for a rails app, has_many through为 rails 应用程序设置模型和关系的正确方法,has_many through
【发布时间】:2023-03-12 08:15:01
【问题描述】:

我很难找到在 Rails 中设置模型和关系的最佳方式,因为我需要 Rails、mvc 和活动记录约定。

考虑三个表:

用户

rails generate scaffold User username:string email:string password:string

游戏

rails generate scaffold Game user_id:integer name:string description:string type:string

game_rosters

rails generate scaffold GameRoster user_id:integer game_id:integer level:integer status:string

用户可以创建游戏(这是游戏表中“所有者”的 user_id 字段)。创建者可能在也可能不在实际游戏中(game_rosters 表中创建者的可选记录)。

每个游戏都有许多用户,这些用户是游戏的一部分(位于 game_rosters 中)。

所以我想我应该为用户建立两个关系——has_many: games 用于他们创建的游戏,has_many: games, through: game_rosters 用于用户参与的游戏..

class User < ActiveRecord::Base
    has_many :game_rosters
    has_many :games, through: :game_rosters

    has_many :games
end

class Game < ActiveRecord::Base
    has_many :game_rosters
    has_many :users, through: :game_rosters
end

class GameRoster < ActiveRecord::Base
    belongs_to :user
    belongs_to :game
end

但我不确定这是否是正确的设置,并且我无法使其正常工作。我已经进行了上述设置,并且尝试打印结果如下:

<p>
  <strong>My Games:</strong>
  <% @user.games.each do |game| %>
  <br><%= game.name %>
  <% end %>
</p>


<p>
  <strong>Participants:</strong>
  <% @game.users do |user| %>
  <br><%= game.user.name %>
  <% end %>
</p>

我可以从has_many: games 关系中打印“我的奥运会”,但不能从has_many :through 关系中打印“参与者”。

任何方向都将不胜感激,谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    还想补充一点,games 模型中的不同关联不应具有相同的名称 games。因为最后一个覆盖了第一个。像这样的东西应该可以工作。

    class User < ActiveRecord::Base
    
        has_many :owned_games, :foreign_key => "user_id", :class_name => "Game"
    
        has_many :game_rosters
        has_many :games, through: :game_rosters
    
    
    end
    
    class Game < ActiveRecord::Base
    
        belongs_to :owner, :foreign_key => "user_id", :class_name => "Game"
    
        has_many :game_rosters
        has_many :users, through: :game_rosters
    end
    
    class GameRoster < ActiveRecord::Base
        belongs_to :user
        belongs_to :game
    end
    

    访问用户的关联

     # All the games a user is involved in 
     user.games
    
     # All the games a user owns
     user.owned_games
    

    访问游戏的关联

     #All the users involved in the game
     game.users
    
    # Owner of the game
     game.owner
    

    【讨论】:

    • 哦,这就是我担心的问题,如果我的关系设置正确,我现在就试试你的建议。
    • 因此,如果我在用户显示视图 /users/1 中并尝试打印出我参与的游戏,我将如何访问该数据?我可以通过 user.games.each 获得我拥有的游戏。
    • 更新了答案。简而言之,按照我建议的方案,user.games 通过game_roster 提供用户参与的游戏,user.owned_games 提供用户拥有的游戏。
    • 对不起,愚蠢的问题,但是说当访问游戏的关联时,我想获得 game_rosters 表中的“级别”属性?我无法获取这些数据。
    • game.game_rosters 返回与game 关联的game_rosters 数组。该数组的每个元素都是game_roster 表的一个对象。所以game.game_rosters.map{|x| x.levels} 为所有关联的game_rosters 返回一个levels 数组。阅读docs 可能会很好
    【解决方案2】:

    试试:

    <p>
      <strong>Participants:</strong>
      <% @game.users.each do |user| %>
      <br><%= user.name %>
      <% end %>
    </p>
    

    【讨论】:

    • 所以我修复了“.each”,并且 user.name 抛出了未定义的方法“名称”错误。当我执行 user.id 时,它可以正常工作 - 使用 through: game_rosters 关系从 Games 控制器显示时从 Users 模型访问名称的正确方法是什么?
    • @canigetabreak 用户有name 属性吗?
    • 哦,哇,对不起。我必须放慢速度。谢谢您的帮助!!所以我在上面的关系设置看起来不错?
    • @canigetabreak 哈哈,好吧,不知道这到底是什么意思……很高兴我能帮上忙。 :)
    • @canigetabreak 我在用户关系中看到一个错误,因为games 用于定义两个关联。
    猜你喜欢
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    相关资源
    最近更新 更多