Rails / Mongoid保存可排序有序列表的最佳方法

时间:2014-02-11 03:07:33

标签: ruby-on-rails gem mongoid jquery-ui-sortable

我有一个从我的数据库中拉出的可排序的球员名单。用户可以按照自己的喜好对其进行排名。

在与每个玩家的偏好相关联的数据库中存储该订单的最佳方式是什么,并以相同的顺序检索玩家统计数据?

现在我正在@playersdraftlist = @draftlist.map { |id| Player.find(id) }进行检索,但这会多次击中数据库。

所以,目前,我有一个User模型和一个Draft模型。草稿只有一个相关的user_id

1)将draftees存储为用户字段而不是单独的模型会更好吗?

2)当我需要保留欺骗和订单时,是否有更好的方法来存储这样的列表?

结构:

PlayerDraft模型具有关联的user_id

  draftees: [
    "52f4fd9f52e39bc0c15674ea", #Peyton
    "52f4fd9f52e39bc0c15674eb", #Tom
    "52f4fd9f52e39bc0c15674ea"  #Peyton
  ],
  user_id: "52f581096b657612fe020000"

@draftees = Draft.find(user_id = current_user._id).first.draftees将返回draftees数组。

调用Player.find(@draftees)将删除重复项并按_id排序。

修改

这是我糟糕的解决方案:

  def index
    @players = Player.all

    if current_user.draft_list.draftees == [""]
      @playersdraftlist = ""

    else
      # Get all picks for current user
      @picks = current_user.draft_list.draftees
      @draft = Player.find(@picks)
      @playersdraftlist = @picks.map { |id| Player.find(id) }

    end
  end

1 个答案:

答案 0 :(得分:2)

这样做的方法是在mongoid中使用身份映射。 这里有更多详细信息:http://mongoid.org/en/mongoid/docs/identity_map.html

但是,执行此操作的简单方法是在mongoid.yml设置以下属性: identity_map_enabled: true

然后搜索以下内容:Player.find(@draftees) 这将按照您传入的数组的顺序返回您的被引用者。一个警告是它不会返回重复项,因此如果使用上面的@draftees数组将只返回两个值(顺序基于第一次出现id,所以它将首先返回id为“52f4fd9f52e39bc0c15674ea”的玩家,然后返回id为“52f4fd9f52e39bc0c15674eb”的玩家。因此,您必须通过某种抽象来重新创建重复项。

这是一种可能的方法,它的灵感来自下面@muistooshort发布的评论:

User课程中添加以下功能

def get_draftee_list
  players = Player.find(self.draftees).each_with_object({}) { |p, h| h[p.id] = p } 
  return self.draftees.map { |id| players[Moped::BSON::ObjectId.from_string(id)] }
end

注意:这是在Mongoid 3上测试的

这应该可以解决您的问题,因为每次调用raw_data.find(id)都是从初始查询中搜索结果集,该查询存储在内存中而不是对db进行另一次查询