Skip to content

Commit

Permalink
Merge pull request #44 from agoragames/custom-data-keys
Browse files Browse the repository at this point in the history
Custom data keys
  • Loading branch information
czarneckid committed Jan 25, 2014
2 parents 2eca1f2 + 626fcf6 commit a3fe7b3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 23 deletions.
29 changes: 16 additions & 13 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,35 @@ Create a new leaderboard or attach to an existing leaderboard named 'highscores'
=> #<Leaderboard:0x0000010307b530 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/0 (Redis v2.2.5)>>
```

If you need to pass in options for Redis, you can do this in the initializer:

```ruby
redis_options = {:host => 'localhost', :port => 6379, :db => 1}
=> {:host=>"localhost", :port=>6379, :db=>1}
highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
=> #<Leaderboard:0x00000103095200 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/1 (Redis v2.2.5)>>
```

### Defining leaderboard options

The `Leaderboard::DEFAULT_OPTIONS` are as follows:

```ruby
DEFAULT_OPTIONS = {
:page_size => DEFAULT_PAGE_SIZE,
:reverse => false
:reverse => false,
:member_key => :member,
:rank_key => :rank,
:score_key => :score,
:member_data_key => :member_data
}
```

The `DEFAULT_PAGE_SIZE` is 25.

You would use the option, `:reverse => true`, if you wanted a leaderboard sorted from lowest-to-highest score. You
may also set the `reverse` option on a leaderboard after you have created a new instance of a leaderboard.
You would use the option, `:reverse => true`, if you wanted a leaderboard sorted from lowest-to-highest score. You may also set the `reverse` option on a leaderboard after you have created a new instance of a leaderboard. The various `..._key` options above control what data is returned in the hash of leaderboard data from calls such as `leaders` or `around_me`.

If you need to pass in options for Redis, you can do this in the initializer:

```ruby
redis_options = {:host => 'localhost', :port => 6379, :db => 1}
=> {:host=>"localhost", :port=>6379, :db=>1}
highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
=> #<Leaderboard:0x00000103095200 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/1 (Redis v2.2.5)>>
```

You can pass in an existing connection to Redis using `:redis_connection` in the Redis options hash:
You can pass in an existing connection to Redis using `:redis_connection` in the `redis_options` hash:

```ruby
redis = Redis.new
Expand Down
31 changes: 21 additions & 10 deletions lib/leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class Leaderboard
# highest-to-lowest order.
DEFAULT_OPTIONS = {
:page_size => DEFAULT_PAGE_SIZE,
:reverse => false
:reverse => false,
:member_key => :member,
:rank_key => :rank,
:score_key => :score,
:member_data_key => :member_data
}

# Default Redis host: localhost
Expand Down Expand Up @@ -60,13 +64,20 @@ class Leaderboard
# leaderboard = Leaderboard.new('highscores')
# leaderboard = Leaderboard.new('highscores', {:page_size => 10})
def initialize(leaderboard_name, options = DEFAULT_OPTIONS, redis_options = DEFAULT_REDIS_OPTIONS)
leaderboard_options = DEFAULT_OPTIONS.dup
leaderboard_options.merge!(options)

@leaderboard_name = leaderboard_name

@reverse = options[:reverse]
@page_size = options[:page_size]
@reverse = leaderboard_options[:reverse]
@page_size = leaderboard_options[:page_size]
if @page_size.nil? || @page_size < 1
@page_size = DEFAULT_PAGE_SIZE
end
@member_key = leaderboard_options[:member_key]
@rank_key = leaderboard_options[:rank_key]
@score_key = leaderboard_options[:score_key]
@member_data_key = leaderboard_options[:member_data_key]

@redis_connection = redis_options[:redis_connection]
unless @redis_connection.nil?
Expand Down Expand Up @@ -440,7 +451,7 @@ def score_and_rank_for_in(leaderboard_name, member)
responses[0] = responses[0].to_f if responses[0]
responses[1] = responses[1] + 1 rescue nil

{:member => member, :score => responses[0], :rank => responses[1]}
{@member_key => member, @score_key => responses[0], @rank_key => responses[1]}
end

# Remove members from the leaderboard in a given score range.
Expand Down Expand Up @@ -912,24 +923,24 @@ def ranked_in_list_in(leaderboard_name, members, options = {})

members.each_with_index do |member, index|
data = {}
data[:member] = member
data[@member_key] = member
unless leaderboard_options[:members_only]
data[:rank] = responses[index * 2] + 1 rescue nil
data[:score] = responses[index * 2 + 1].to_f if responses[index * 2 + 1]
data[@rank_key] = responses[index * 2] + 1 rescue nil
data[@score_key] = responses[index * 2 + 1].to_f if responses[index * 2 + 1]
end

if leaderboard_options[:with_member_data]
data[:member_data] = member_data_for_in(leaderboard_name, member)
data[@member_data_key] = member_data_for_in(leaderboard_name, member)
end

ranks_for_members << data
end

case leaderboard_options[:sort_by]
when :rank
ranks_for_members = ranks_for_members.sort_by { |member| member[:rank] }
ranks_for_members = ranks_for_members.sort_by { |member| member[@rank_key] }
when :score
ranks_for_members = ranks_for_members.sort_by { |member| member[:score] }
ranks_for_members = ranks_for_members.sort_by { |member| member[@score_key] }
end

ranks_for_members
Expand Down
24 changes: 24 additions & 0 deletions spec/leaderboard_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -735,4 +735,28 @@
@leaderboard.leaders_in('highscores', 1).size.should eql(1)
@leaderboard.leaders_in('more_highscores', 1).size.should eql(1)
end

it 'should allow you to set custom keys for member, score, rank and member_data' do
@leaderboard = Leaderboard.new('name',
{
:member_key => :custom_member_key,
:rank_key => :custom_rank_key,
:score_key => :custom_score_key,
:member_data_key => :custom_member_data_key
},
{:host => "127.0.0.1", :db => 15})

rank_members_in_leaderboard(5)
leaders = @leaderboard.leaders(1, :with_member_data => true)
leaders.each do |leader|
leader[:custom_member_key].should_not be_nil
leader[:member].should be_nil
leader[:custom_score_key].should_not be_nil
leader[:score].should be_nil
leader[:custom_rank_key].should_not be_nil
leader[:rank].should be_nil
leader[:custom_member_data_key].should_not be_nil
leader[:member_data].should be_nil
end
end
end

0 comments on commit a3fe7b3

Please sign in to comment.