Module: LikesTracker::ClassMethods

Defined in:
lib/likes_tracker.rb

Instance Method Summary collapse

Instance Method Details

#acts_as_liked_by(model) ⇒ Object

acts_as_liker_for



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/likes_tracker.rb', line 54

def acts_as_liked_by(model)
  model_name = model.to_s.singularize.downcase
  model_class = model.to_s.singularize.capitalize.constantize

  model_table = model_name.pluralize

  liker_key = "#{model_table}:likers"

  # count received likes
  define_method "likes_#{model_name.pluralize}_count" do
    $redis.scard self.redis_key(liker_key)
  end

  # find the first <limit> <object>s with more likes
  define_singleton_method :most_liked do |limit=5, offset=0, &block|
    limit -= 1 if (limit > 0)
    most_liked_key = "#{self.name.downcase.pluralize}:like_scores"
    most_liked_ids = $redis.zrevrange(most_liked_key, offset, limit)

    if block
      blk = ->(klass, params) { block.call(klass, params) }
      blk.call(self, most_liked_ids)
    else
      self.where(id: most_liked_ids).order(most_liked_ids.map {|id| "id = #{id} DESC"}.join(','))
    end
  end

end

#acts_as_liker_for(model) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/likes_tracker.rb', line 7

def acts_as_liker_for(model)
  model_name = model.to_s.singularize.downcase
  model_class = model.to_s.singularize.capitalize.constantize

  model_table = model_name.pluralize
  self_table = self.name.downcase.pluralize

  liker_key = "#{model_table}:likes"
  liked_key = "#{self_table}:likers"

  # like <object>
  define_method "like_#{model_name}!" do |obj|
    $redis.multi do
      $redis.sadd(self.redis_key(liker_key), obj.id)
      $redis.sadd(obj.redis_key(liked_key), self.id)
      $redis.zincrby("#{model_table}:like_scores", 1, obj.id)
    end unless self.send("likes_#{model_name}?", obj)
  end

  # remove like from <object>
  define_method "unlike_#{model_name}!" do |obj|
    $redis.multi do
      $redis.srem(self.redis_key(liker_key), obj.id)
      $redis.srem(obj.redis_key(liked_key), self.id)
      $redis.zincrby("#{model_table}:like_scores", -1, obj.id)
    end if self.send("likes_#{model_name}?", obj)
  end

  # checks if <object> is liked or not
  define_method "likes_#{model_name}?" do |obj|
    $redis.sismember(self.redis_key(liker_key), obj.id)
  end

  # find liked <object>s
  define_method "liked_#{model_name.pluralize}" do |&block|
    liked_ids = $redis.smembers self.redis_key(liker_key)

    if block
      blk = ->(klass, params) { block.call(klass, params) }
      blk.call(model_class, liked_ids)
    else
      model_class.where(id: liked_ids)
    end
  end

end