9

在我的rails应用程序中,我有两个与has_and_belongs_to_many相关的模型。这意味着有一个连接表。has_and_belongs_to_many关联的排序

想象一下我将用户添加到游戏中的场景。如果我想添加用户,我需要:

@game.users << @user 

假设我想知道按什么顺序添加了这些用户。我可以这样做:

@game.users.each do.... 

我的问题是:

  1. 是,如果该列表保证每次读取相同的方式排序?

  2. 如果是这样的话,什么是干净的方式来重新排序游戏中的用户?

回答

18

要在danivo的回答底部展开:

如果你想将其添加到这个列表中的时间订购那么我建议,而不是使用has_and_belongs_to_many你实际使用has_many :through

game.rb

has_many :played_games 
has_many :users, :through => :played_games, :order => "played_games.created_at ASC" 

user.rb

has_many :played_games 
has_many :games, :through => :played_games 

played_game.rb

belongs_to :game 
belongs_to :user 

当然,改变上的名字待定...

played_games表,如果你有一列名为created_at第二has_many游戏将按此字段排序,并按用户添加到游戏中的顺序返回用户。

+0

我认为这可以为我工作...给更多的上下文 - 我不需要按用户名排序,而是我想要服务器随机选择一个订单,以便游戏中的玩家位置由它决定。所以我想我可以在playing_game表中放置一个'player_index'字段,并且在我想决定谁先移动的点上提供索引.... – cmaughan 2009-11-10 13:21:28

11

我不能肯定,但我要说的是,作为数据库保证了结果集,而不order by子句的顺序排序为保证相同。

您可以将:order => "last_name, first_name asc"添加到:has_and_belongs_to_many关系语句中。这将为返回项目的顺序设置默认行为。

您也可以使用@game.users.find(:all, :order => "last_name, first_name asc")或为您需要的常用排序创建命名范围。 Check out the api for details

如果知道您添加它们的顺序非常重要,那么您可能希望切换到has_many :through关系,以便连接表具有自己的实体。然后,您将拥有由rails管理的关系的created_onupdated_on时间戳。

+0

SQL标准没有明确说明排序。这通常是创建顺序,因为结果集被汇编时记录会被拾取,但这只是一个巧合。一个有很多更新的数据库可能会有遍布整个地方的记录。用户订购,如果它很重要。我已经在Rails中用#last为postgres返回了不同的东西。 – Ghoti 2014-07-10 12:37:03