acts_as_follower 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +10 -8
- data/Rakefile +1 -3
- data/lib/acts_as_follower.rb +2 -3
- data/lib/acts_as_follower/follow_scopes.rb +37 -0
- data/lib/acts_as_follower/followable.rb +12 -12
- data/lib/acts_as_follower/follower.rb +16 -15
- data/lib/acts_as_follower/follower_lib.rb +3 -3
- data/lib/acts_as_follower/railtie.rb +3 -3
- data/lib/acts_as_follower/version.rb +1 -1
- data/lib/generators/templates/model.rb +5 -12
- data/test/acts_as_followable_test.rb +15 -0
- data/test/acts_as_follower_test.rb +1 -1
- metadata +5 -4
    
        data/README.rdoc
    CHANGED
    
    | @@ -191,14 +191,16 @@ If you have updates or patches or want to contribute I would love to see what yo | |
| 191 191 |  | 
| 192 192 | 
             
            Thanks to everyone for their interest and time in committing to making this plugin better.
         | 
| 193 193 |  | 
| 194 | 
            -
            * dougal (Douglas F Shearer) -  | 
| 195 | 
            -
            * jdg (Jonathan George) -  | 
| 196 | 
            -
            * m3talsmith (Michael Christenson II) -  | 
| 197 | 
            -
            * joergbattermann (Jörg Battermann) -  | 
| 198 | 
            -
            * TomK32 (Thomas R. Koll) -  | 
| 199 | 
            -
            * drcapulet (Alex Coomans) -  | 
| 200 | 
            -
            * jhchabran (Jean Hadrien Chabran) -  | 
| 201 | 
            -
            * arthurgeek (Arthur Zapparoli) -  | 
| 194 | 
            +
            * dougal (Douglas F Shearer) - https://github.com/dougal
         | 
| 195 | 
            +
            * jdg (Jonathan George) - https://github.com/jdg
         | 
| 196 | 
            +
            * m3talsmith (Michael Christenson II) - https://github.com/m3talsmith
         | 
| 197 | 
            +
            * joergbattermann (Jörg Battermann) - https://github.com/joergbattermann
         | 
| 198 | 
            +
            * TomK32 (Thomas R. Koll) - https://github.com/TomK32
         | 
| 199 | 
            +
            * drcapulet (Alex Coomans) - https://github.com/drcapulet
         | 
| 200 | 
            +
            * jhchabran (Jean Hadrien Chabran) - https://github.com/jhchabran
         | 
| 201 | 
            +
            * arthurgeek (Arthur Zapparoli) - https://github.com/arthurgeek
         | 
| 202 | 
            +
            * james2m (James McCarthy) - https://github.com/james2m
         | 
| 203 | 
            +
            * peterjm (Peter McCracken) - https://github.com/peterjm
         | 
| 202 204 |  | 
| 203 205 | 
             
            Please let me know if I missed you.
         | 
| 204 206 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -25,7 +25,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc| | |
| 25 25 | 
             
            end
         | 
| 26 26 |  | 
| 27 27 | 
             
            namespace :rcov do
         | 
| 28 | 
            -
             | 
| 29 28 | 
             
              desc "Generate a coverage report in coverage/"
         | 
| 30 29 | 
             
              task :gen do
         | 
| 31 30 | 
             
                sh "rcov --output coverage test/*_test.rb --exclude 'gems/*'"
         | 
| @@ -35,5 +34,4 @@ namespace :rcov do | |
| 35 34 | 
             
              task :clobber do
         | 
| 36 35 | 
             
                sh "rm -rdf coverage"
         | 
| 37 36 | 
             
              end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
            end
         | 
| 37 | 
            +
            end
         | 
    
        data/lib/acts_as_follower.rb
    CHANGED
    
    | @@ -4,8 +4,7 @@ module ActsAsFollower | |
| 4 4 | 
             
              autoload :Follower,     'acts_as_follower/follower'
         | 
| 5 5 | 
             
              autoload :Followable,   'acts_as_follower/followable'
         | 
| 6 6 | 
             
              autoload :FollowerLib,  'acts_as_follower/follower_lib'
         | 
| 7 | 
            -
              
         | 
| 7 | 
            +
              autoload :FollowScopes, 'acts_as_follower/follow_scopes'
         | 
| 8 | 
            +
             | 
| 8 9 | 
             
              require 'acts_as_follower/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
         | 
| 9 10 | 
             
            end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module ActsAsFollower #:nodoc:
         | 
| 2 | 
            +
              module FollowScopes
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def for_follower(follower)
         | 
| 5 | 
            +
                  where(:follower_id => follower.id, :follower_type => parent_class_name(follower))
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def for_followable(followable)
         | 
| 9 | 
            +
                  where(:followable_id => followable.id, :followable_type => parent_class_name(followable))
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def for_follower_type(follower_type)
         | 
| 13 | 
            +
                  where(:follower_type => follower_type)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def for_followable_type(followable_type)
         | 
| 17 | 
            +
                  where(:followable_type => followable_type)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def recent(from)
         | 
| 21 | 
            +
                  where(["created_at > ?", (from || 2.weeks.ago).to_s(:db)])
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def descending
         | 
| 25 | 
            +
                  order("follows.created_at DESC")
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def unblocked
         | 
| 29 | 
            +
                  where(:blocked => false)
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def blocked
         | 
| 33 | 
            +
                  where(:blocked => true)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -13,7 +13,6 @@ module ActsAsFollower #:nodoc: | |
| 13 13 | 
             
                  end
         | 
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 | 
            -
             | 
| 17 16 | 
             
                module InstanceMethods
         | 
| 18 17 |  | 
| 19 18 | 
             
                  # Returns the number of followers a record has.
         | 
| @@ -24,15 +23,17 @@ module ActsAsFollower #:nodoc: | |
| 24 23 | 
             
                  # Returns the followers by a given type
         | 
| 25 24 | 
             
                  def followers_by_type(follower_type, options={})
         | 
| 26 25 | 
             
                    follows = follower_type.constantize.
         | 
| 27 | 
            -
                       | 
| 28 | 
            -
                      where('blocked | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
                      )
         | 
| 26 | 
            +
                      joins(:follows).
         | 
| 27 | 
            +
                      where('follows.blocked'         => false,
         | 
| 28 | 
            +
                            'follows.followable_id'   => self.id, 
         | 
| 29 | 
            +
                            'follows.followable_type' => parent_class_name(self), 
         | 
| 30 | 
            +
                            'follows.follower_type'   => follower_type)
         | 
| 33 31 | 
             
                    if options.has_key?(:limit)
         | 
| 34 32 | 
             
                      follows = follows.limit(options[:limit])
         | 
| 35 33 | 
             
                    end
         | 
| 34 | 
            +
                    if options.has_key?(:includes)
         | 
| 35 | 
            +
                      follows = follows.includes(options[:includes])
         | 
| 36 | 
            +
                    end
         | 
| 36 37 | 
             
                    follows
         | 
| 37 38 | 
             
                  end
         | 
| 38 39 |  | 
| @@ -70,8 +71,7 @@ module ActsAsFollower #:nodoc: | |
| 70 71 | 
             
                  # Returns true if the current instance is followed by the passed record
         | 
| 71 72 | 
             
                  # Returns false if the current instance is blocked by the passed record or no follow is found
         | 
| 72 73 | 
             
                  def followed_by?(follower)
         | 
| 73 | 
            -
                     | 
| 74 | 
            -
                    (f && !f.blocked?) ? true : false
         | 
| 74 | 
            +
                    self.followings.unblocked.for_follower(follower).exists?
         | 
| 75 75 | 
             
                  end
         | 
| 76 76 |  | 
| 77 77 | 
             
                  def block(follower)
         | 
| @@ -82,12 +82,12 @@ module ActsAsFollower #:nodoc: | |
| 82 82 | 
             
                    get_follow_for(follower).try(:delete)
         | 
| 83 83 | 
             
                  end
         | 
| 84 84 |  | 
| 85 | 
            -
                  private
         | 
| 86 | 
            -
             | 
| 87 85 | 
             
                  def get_follow_for(follower)
         | 
| 88 | 
            -
                     | 
| 86 | 
            +
                    self.followings.for_follower(follower).first
         | 
| 89 87 | 
             
                  end
         | 
| 90 88 |  | 
| 89 | 
            +
                  private
         | 
| 90 | 
            +
             | 
| 91 91 | 
             
                  def block_future_follow(follower)
         | 
| 92 92 | 
             
                    follows.create(:followable => self, :follower => follower, :blocked => true)
         | 
| 93 93 | 
             
                  end
         | 
| @@ -28,9 +28,8 @@ module ActsAsFollower #:nodoc: | |
| 28 28 | 
             
                  # Creates a new follow record for this instance to follow the passed object.
         | 
| 29 29 | 
             
                  # Does not allow duplicate records to be created.
         | 
| 30 30 | 
             
                  def follow(followable)
         | 
| 31 | 
            -
                     | 
| 32 | 
            -
             | 
| 33 | 
            -
                      Follow.create(:followable => followable, :follower => self)
         | 
| 31 | 
            +
                    if self != followable
         | 
| 32 | 
            +
                      self.follows.find_or_create_by_followable_id_and_followable_type(followable.id, parent_class_name(followable))
         | 
| 34 33 | 
             
                    end
         | 
| 35 34 | 
             
                  end
         | 
| 36 35 |  | 
| @@ -43,7 +42,7 @@ module ActsAsFollower #:nodoc: | |
| 43 42 |  | 
| 44 43 | 
             
                  # Returns the follow records related to this instance by type.
         | 
| 45 44 | 
             
                  def follows_by_type(followable_type, options={})
         | 
| 46 | 
            -
                     | 
| 45 | 
            +
                    self.follows.unblocked.includes(:followable).for_followable_type(followable_type).all(options)
         | 
| 47 46 | 
             
                  end
         | 
| 48 47 |  | 
| 49 48 | 
             
                  # Returns the follow records related to this instance with the followable included.
         | 
| @@ -58,21 +57,23 @@ module ActsAsFollower #:nodoc: | |
| 58 57 |  | 
| 59 58 | 
             
                  # Returns the actual records of a particular type which this record is following.
         | 
| 60 59 | 
             
                  def following_by_type(followable_type, options={})
         | 
| 61 | 
            -
                     | 
| 62 | 
            -
                       | 
| 63 | 
            -
                      where('blocked | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
                      )
         | 
| 60 | 
            +
                    followables = followable_type.constantize.
         | 
| 61 | 
            +
                      joins(:followings).
         | 
| 62 | 
            +
                      where('follows.blocked'         => false,
         | 
| 63 | 
            +
                            'follows.follower_id'     => self.id, 
         | 
| 64 | 
            +
                            'follows.follower_type'   => parent_class_name(self), 
         | 
| 65 | 
            +
                            'follows.followable_type' => followable_type)
         | 
| 68 66 | 
             
                    if options.has_key?(:limit)
         | 
| 69 | 
            -
                       | 
| 67 | 
            +
                      followables = followables.limit(options[:limit])
         | 
| 70 68 | 
             
                    end
         | 
| 71 | 
            -
                     | 
| 69 | 
            +
                    if options.has_key?(:includes)
         | 
| 70 | 
            +
                      followables = followables.includes(options[:includes])
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
                    followables
         | 
| 72 73 | 
             
                  end
         | 
| 73 74 |  | 
| 74 75 | 
             
                  def following_by_type_count(followable_type)
         | 
| 75 | 
            -
                     | 
| 76 | 
            +
                    follows.unblocked.for_followable_type(followable_type).count
         | 
| 76 77 | 
             
                  end
         | 
| 77 78 |  | 
| 78 79 | 
             
                  # Allows magic names on following_by_type
         | 
| @@ -91,7 +92,7 @@ module ActsAsFollower #:nodoc: | |
| 91 92 |  | 
| 92 93 | 
             
                  # Returns a follow record for the current instance and followable object.
         | 
| 93 94 | 
             
                  def get_follow(followable)
         | 
| 94 | 
            -
                     | 
| 95 | 
            +
                    self.follows.unblocked.for_followable(followable).first
         | 
| 95 96 | 
             
                  end
         | 
| 96 97 |  | 
| 97 98 | 
             
                end
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            module ActsAsFollower
         | 
| 2 2 | 
             
              module FollowerLib
         | 
| 3 | 
            -
             | 
| 3 | 
            +
             | 
| 4 4 | 
             
                private
         | 
| 5 | 
            -
             | 
| 5 | 
            +
             | 
| 6 6 | 
             
                # Retrieves the parent class name if using STI.
         | 
| 7 7 | 
             
                def parent_class_name(obj)
         | 
| 8 8 | 
             
                  if obj.class.superclass != ActiveRecord::Base
         | 
| @@ -10,6 +10,6 @@ module ActsAsFollower | |
| 10 10 | 
             
                  end
         | 
| 11 11 | 
             
                  return obj.class.name
         | 
| 12 12 | 
             
                end
         | 
| 13 | 
            -
             | 
| 13 | 
            +
             | 
| 14 14 | 
             
              end
         | 
| 15 15 | 
             
            end
         | 
| @@ -3,13 +3,13 @@ require 'rails' | |
| 3 3 |  | 
| 4 4 | 
             
            module ActsAsFollower
         | 
| 5 5 | 
             
              class Railtie < Rails::Railtie
         | 
| 6 | 
            -
             | 
| 6 | 
            +
             | 
| 7 7 | 
             
                initializer "acts_as_follower.active_record" do |app|
         | 
| 8 8 | 
             
                  ActiveSupport.on_load :active_record do
         | 
| 9 9 | 
             
                    include ActsAsFollower::Follower
         | 
| 10 10 | 
             
                    include ActsAsFollower::Followable
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 | 
             
                end
         | 
| 13 | 
            -
             | 
| 13 | 
            +
             | 
| 14 14 | 
             
              end
         | 
| 15 | 
            -
            end
         | 
| 15 | 
            +
            end
         | 
| @@ -1,21 +1,14 @@ | |
| 1 1 | 
             
            class Follow < ActiveRecord::Base
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
              extend ActsAsFollower::FollowerLib
         | 
| 3 | 
            -
              
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              scope :for_followable,      lambda { |followable| where(["followable_id = ? AND followable_type = ?", followable.id, parent_class_name(followable)]) }
         | 
| 6 | 
            -
              scope :for_follower_type,   lambda { |follower_type| where("follower_type = ?", follower_type) }
         | 
| 7 | 
            -
              scope :for_followable_type, lambda { |followable_type| where("followable_type = ?", followable_type) }
         | 
| 8 | 
            -
              scope :recent,              lambda { |from| where(["created_at > ?", (from || 2.weeks.ago).to_s(:db)]) }
         | 
| 9 | 
            -
              scope :descending,          order("follows.created_at DESC")
         | 
| 10 | 
            -
              scope :unblocked,           where(:blocked => false)
         | 
| 11 | 
            -
              scope :blocked,             where(:blocked => true)
         | 
| 12 | 
            -
              
         | 
| 4 | 
            +
              extend ActsAsFollower::FollowScopes
         | 
| 5 | 
            +
             | 
| 13 6 | 
             
              # NOTE: Follows belong to the "followable" interface, and also to followers
         | 
| 14 7 | 
             
              belongs_to :followable, :polymorphic => true
         | 
| 15 8 | 
             
              belongs_to :follower,   :polymorphic => true
         | 
| 16 | 
            -
             | 
| 9 | 
            +
             | 
| 17 10 | 
             
              def block!
         | 
| 18 11 | 
             
                self.update_attribute(:blocked, true)
         | 
| 19 12 | 
             
              end
         | 
| 20 | 
            -
             | 
| 13 | 
            +
             | 
| 21 14 | 
             
            end
         | 
| @@ -84,6 +84,21 @@ class ActsAsFollowableTest < ActiveSupport::TestCase | |
| 84 84 | 
             
                  should_change("@sam.all_following.size", :by => -1) { @sam.all_following.size }
         | 
| 85 85 | 
             
                end
         | 
| 86 86 |  | 
| 87 | 
            +
                context "get follow record" do
         | 
| 88 | 
            +
                  setup do
         | 
| 89 | 
            +
                    @bob = Factory(:bob)
         | 
| 90 | 
            +
                    @follow = @bob.follow(@sam)
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  should "return follow record" do
         | 
| 94 | 
            +
                    assert_equal @follow, @sam.get_follow_for(@bob)
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  should "return nil" do
         | 
| 98 | 
            +
                    assert_nil @sam.get_follow_for(@jon)
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 87 102 | 
             
                context "blocks" do
         | 
| 88 103 | 
             
                  setup do
         | 
| 89 104 | 
             
                    @bob = Factory(:bob)
         | 
| @@ -148,7 +148,7 @@ class ActsAsFollowerTest < ActiveSupport::TestCase | |
| 148 148 | 
             
                  should "accept AR options" do
         | 
| 149 149 | 
             
                    @metallica = Factory(:metallica)
         | 
| 150 150 | 
             
                    @sam.follow(@metallica)
         | 
| 151 | 
            -
                    assert_equal 1, @sam.following_by_type('Band', :limit => 1). | 
| 151 | 
            +
                    assert_equal 1, @sam.following_by_type('Band', :limit => 1).to_a.size
         | 
| 152 152 | 
             
                  end
         | 
| 153 153 | 
             
                end
         | 
| 154 154 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: acts_as_follower
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 25
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 8 | 
             
              - 1
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0.1. | 
| 9 | 
            +
              - 1
         | 
| 10 | 
            +
              version: 0.1.1
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Tom Cocca
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2011- | 
| 18 | 
            +
            date: 2011-11-06 01:00:00 -04:00
         | 
| 19 19 | 
             
            default_executable: 
         | 
| 20 20 | 
             
            dependencies: 
         | 
| 21 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -94,6 +94,7 @@ files: | |
| 94 94 | 
             
            - acts_as_follower.gemspec
         | 
| 95 95 | 
             
            - init.rb
         | 
| 96 96 | 
             
            - lib/acts_as_follower.rb
         | 
| 97 | 
            +
            - lib/acts_as_follower/follow_scopes.rb
         | 
| 97 98 | 
             
            - lib/acts_as_follower/followable.rb
         | 
| 98 99 | 
             
            - lib/acts_as_follower/follower.rb
         | 
| 99 100 | 
             
            - lib/acts_as_follower/follower_lib.rb
         |