Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom data keys #44

Merged
merged 2 commits into from
Jan 25, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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