문제

I've got a sortable list of players pulled from my db. Users can rank them in order of their preference.

What's the best way to store that order in the db associated with each player's preference and retrieve player stats back in that same order?

Right now I'm retrieving by @playersdraftlist = @draftlist.map { |id| Player.find(id) }, but this hits the db many times.

So, currently, I have a User model and a Draft model. The draft only has an associated user_id.

1) Would it be better to just store the draftees as a user field instead of a separate model?

2) Is there a better way to store a list like this when I need to retain dupes and order?

Structure:

PlayerDraft model has an associated user_id:

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

@draftees = Draft.find(user_id = current_user._id).first.draftees will return the draftees array.

Calling Player.find(@draftees) will remove the duplicates and order by _id.

Edit

Here is my poor solution:

  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
도움이 되었습니까?

해결책

The way to do this is to use the identity map in mongoid. There are more details on this here: http://mongoid.org/en/mongoid/docs/identity_map.html

But the short and simple way to do this is in your mongoid.yml set the following property: identity_map_enabled: true

Then search for the following: Player.find(@draftees) And this will return your draftees in the order of the array that you passed in. One caveat is that it won't return duplicates so your @draftees array above if used would return only two values (the order is based on the first appearance of the id, so it will return the player with id "52f4fd9f52e39bc0c15674ea" first and then the player with id "52f4fd9f52e39bc0c15674eb"). So you will have to recreate the duplicates via some sort of abstraction.

Here is one possible way to do this, and it was inspired by a comment posted by @muistooshort below:

In your User class add the following function

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

Note: This was tested on Mongoid 3

This should solve your problem since each call to raw_data.find(id) is searching the result set from your the initial query which is stored in memory and not making another query to the db

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top