Let's cache our gems in vendor/cache! (#8066)

* Let's cache our gems in vendor/cache!

This PR adds in bundle package caching which will help speed up deployments by
caching all of the gems that we use in our git repo. This was done with the
following commands on a fresh repo clone:

bundle install
bundle package --all

This cached all of our gems in vendor/cache and when you do a bundle install to
update gems from the Gemfile, it will update our gem cache too.

You can read more about bundle package here:

https://bundler.io/man/bundle-package.1.html

* Add in bundle config set cache_all true to bin/setup so it gets set for everyone.
This commit is contained in:
Joe Doss 2020-05-27 11:29:55 -05:00 committed by GitHub
parent 9a489adc12
commit f7a3664415
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
396 changed files with 1645 additions and 0 deletions

View file

@ -15,6 +15,7 @@ FileUtils.chdir APP_ROOT do
puts "== Installing dependencies =="
system! "gem install bundler --conservative"
system! "bundle config set cache_all true"
system("bundle check") || system!("bundle install")
system! "gem install foreman"

BIN
vendor/cache/actioncable-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/actionmailer-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/actionpack-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/actionview-5.2.4.3.gem vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/cache/activejob-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/activemodel-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/activerecord-5.2.4.3.gem vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/cache/activestorage-5.2.4.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/activesupport-5.2.4.3.gem vendored Normal file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,8 @@
test/debug.log
coverage
rdoc
memory
*.gem
.rvmrc
Gemfile.lock
log

View file

@ -0,0 +1,8 @@
language: ruby
rvm:
- 2.2.5
- 2.3.1
env:
matrix:
- "RAILS_VERSION=4.2.7.1"
- "RAILS_VERSION=5.0.0.1"

View file

@ -0,0 +1,6 @@
source "http://rubygems.org"
# Specify your gem's dependencies in acts_as_follower.gemspec
gemspec
gem 'activesupport', ENV['RAILS_VERSION'] if ENV['RAILS_VERSION']

View file

@ -0,0 +1,44 @@
Copyright (c) 2008 Tom Cocca
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The major design pattern of this plugin was abstracted from Peter Jackson's VoteFu, which is subject to the same license.
Here is the original copyright notice for VoteFu:
Copyright (c) 2008 Peter Jackson (peteonrails.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,247 @@
= acts_as_follower
acts_as_follower is a gem to allow any model to follow any other model. This is accomplished through a double polymorphic relationship on the Follow model. There is also built in support for blocking/un-blocking follow records.
Main uses would be for Users to follow other Users or for Users to follow Books, etc...
(Basically, to develop the type of follow system that GitHub has)
{<img src="https://travis-ci.org/tcocca/acts_as_follower.png" />}[https://travis-ci.org/tcocca/acts_as_follower]
== Installation
=== The master branch supports Rails 5
Add the gem to the gemfile:
gem 'acts_as_follower', github: 'tcocca/acts_as_follower', branch: 'master'
Other instructions same as for Rails 4.
=== Rails 4.x support
The first release that support Rails 4 is 0.2.0
Add the gem to the gemfile:
gem "acts_as_follower"
Run the generator:
rails generate acts_as_follower
This will generate a migration file as well as a model called Follow.
=== Rails 3.x support
Rails 3 is supports in the rails_3 branch https://github.com/tcocca/acts_as_follower/tree/rails_3
The last gem release for Rails 3 support was 0.1.1, so install the gem using ~> 0.1.1
Add the gem to the gemfile:
gem "acts_as_follower", '~> 0.1.1'
or install from the branch
gem "acts_as_follower", git: 'git://github.com/tcocca/acts_as_follower.git', branch: 'rails_3'
Run the generator:
rails generate acts_as_follower
This will generate a migration file as well as a model called Follow.
=== Rails 2.3.x support
Rails 2.3.x is supported in the rails_2.3.x branch http://github.com/tcocca/acts_as_follower/tree/rails_2.3.x but must be installed as a plugin.
The gem version does not work with rails 2.3.x.
Run the following command:
script/plugin install git://github.com/tcocca/acts_as_follower.git -r rails_2.3.x
Run the generator:
script/generate acts_as_follower
== Usage
=== Setup
Make your model(s) that you want to allow to be followed acts_as_followable, just add the mixin:
class User < ActiveRecord::Base
...
acts_as_followable
...
end
class Book < ActiveRecord::Base
...
acts_as_followable
...
end
Make your model(s) that can follow other models acts_as_follower
class User < ActiveRecord::Base
...
acts_as_follower
...
end
---
=== acts_as_follower methods
To have an object start following another use the following:
book = Book.find(1)
user = User.find(1)
user.follow(book) # Creates a record for the user as the follower and the book as the followable
To stop following an object use the following
user.stop_following(book) # Deletes that record in the Follow table
You can check to see if an object that acts_as_follower is following another object through the following:
user.following?(book) # Returns true or false
To get the total number (count) of follows for a user use the following on a model that acts_as_follower
user.follow_count # Returns an integer
To get follow records that have not been blocked use the following
user.all_follows # returns an array of Follow records
To get all of the records that an object is following that have not been blocked use the following
user.all_following
# Returns an array of every followed object for the user, this can be a collection of different object types, eg: User, Book
To get all Follow records by a certain type use the following
user.follows_by_type('Book') # returns an array of Follow objects where the followable_type is 'Book'
To get all followed objects by a certain type use the following.
user.following_by_type('Book') # Returns an array of all followed objects for user where followable_type is 'Book', this can be a collection of different object types, eg: User, Book
There is also a method_missing to accomplish the exact same thing a following_by_type('Book') to make you life easier
user.following_users # exact same results as user.following_by_type('User')
To get the count of all Follow records by a certain type use the following
user.following_by_type_count('Book') # Returns the sql count of the number of followed books by that user
There is also a method_missing to get the count by type
user.following_books_count # Calls the user.following_by_type_count('Book') method
There is now a method that will just return the Arel scope for follows so that you can chain anything else you want onto it:
book.follows_scoped
This does not return the actual follows, just the scope of followings including the followables, essentially: book.follows.unblocked.includes(:followable)
The following methods take an optional hash parameter of ActiveRecord options (:limit, :order, etc...)
follows_by_type, all_follows, all_following, following_by_type
---
=== acts_as_followable methods
To get all the followers of a model that acts_as_followable
book.followers # Returns an array of all the followers for that book, a collection of different object types (eg. type User or type Book)
There is also a method that will just return the Arel scope for followers so that you can chain anything else you want onto it:
book.followers_scoped
This does not return the actual followers, just the scope of followings including the followers, essentially: book.followings.includes(:follower)
To get just the number of follows use
book.followers_count
To get the followers of a certain type, eg: all followers of type 'User'
book.followers_by_type('User') # Returns an array of the user followers
There is also a method_missing for this to make it easier:
book.user_followers # Calls followers_by_type('User')
To get just the sql count of the number of followers of a certain type use the following
book.followers_by_type_count('User') # Return the count on the number of followers of type 'User'
Again, there is a method_missing for this method as well
book.count_user_followers # Calls followers_by_type_count('User')
To see is a model that acts_as_followable is followed by a model that acts_as_follower use the following
book.followed_by?(user)
# Returns true if the current instance is followed by the passed record
# Returns false if the current instance is blocked by the passed record or no follow is found
To block a follower call the following
book.block(user)
# Blocks the user from appearing in the followers list, and blocks the book from appearing in the user.all_follows or user.all_following lists
To unblock is just as simple
book.unblock(user)
To get all blocked records
book.blocks # Returns an array of blocked follower records (only unblocked) (eg. type User or type Book)
If you only need the number of blocks use the count method provided
book.blocked_followers_count
Unblocking deletes all records of that follow, instead of just the :blocked attribute => false the follow is deleted. So, a user would need to try and follow the book again.
I would like to hear thoughts on this, I may change this to make the follow as blocked: false instead of deleting the record.
The following methods take an optional hash parameter of ActiveRecord options (:limit, :order, etc...)
followers_by_type, followers, blocks
---
=== Follow Model
The Follow model has a set of named_scope's. In case you want to interface directly with the Follow model you can use them.
Follow.unblocked # returns all "unblocked" follow records
Follow.blocked # returns all "blocked" follow records
Follow.descending # returns all records in a descending order based on created_at datetime
This method pulls all records created after a certain date. The default is 2 weeks but it takes an optional parameter.
Follow.recent
Follow.recent(4.weeks.ago)
Follow.for_follower is a named_scope that is mainly there to reduce code in the modules but it could be used directly. It takes an object and will return all Follow records where the follower is the record passed in. Note that this will return all blocked and unblocked records.
Follow.for_follower(user)
If you don't need the blocked records just use the methods provided for this:
user.all_follows
# or
user.all_following
Follow.for_followable acts the same as its counterpart (for_follower). It is mainly there to reduce duplication, however it can be used directly. It takes an object that is the followed object and return all Follow records where that record is the followable. Again, this returns all blocked and unblocked records.
Follow.for_followable(book)
Again, if you don't need the blocked records use the method provided for this:
book.followers
If you need blocked records only
book.blocks
== Comments/Requests
If anyone has comments or questions please let me know (tom dot cocca at gmail dot com).
If you have updates or patches or want to contribute I would love to see what you have or want to add.
== Note on Patches/Pull Requests
* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a future version unintentionally (acts_as_follower uses Shoulda and Factory Girl)
* Send me a pull request. Bonus points for topic branches.
== Contributers
Thanks to everyone for their interest and time in committing to making this plugin better.
* dougal (Douglas F Shearer) - https://github.com/dougal
* jdg (Jonathan George) - https://github.com/jdg
* m3talsmith (Michael Christenson II) - https://github.com/m3talsmith
* joergbattermann (Jörg Battermann) - https://github.com/joergbattermann
* TomK32 (Thomas R. Koll) - https://github.com/TomK32
* drcapulet (Alex Coomans) - https://github.com/drcapulet
* jhchabran (Jean Hadrien Chabran) - https://github.com/jhchabran
* arthurgeek (Arthur Zapparoli) - https://github.com/arthurgeek
* james2m (James McCarthy) - https://github.com/james2m
* peterjm (Peter McCracken) - https://github.com/peterjm
* merqlove (Alexander Merkulov) - https://github.com/merqlove
Please let me know if I missed you.
== Copyright
Copyright (c) 2008 - 2010 ( tom dot cocca at gmail dot com ), released under the MIT license.

View file

@ -0,0 +1,37 @@
require 'bundler'
Bundler::GemHelper.install_tasks
require 'rake'
require 'rake/testtask'
require 'rdoc/task'
desc 'Default: run unit tests.'
task default: :test
desc 'Test the acts_as_follower gem.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the acts_as_follower gem.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Acts As Follower'
rdoc.main = 'README.rdoc'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
end
namespace :rcov do
desc "Generate a coverage report in coverage/"
task :gen do
sh "rcov --output coverage test/*_test.rb --exclude 'gems/*'"
end
desc "Remove generated coverage files."
task :clobber do
sh "rm -rdf coverage"
end
end

View file

@ -0,0 +1,42 @@
# -*- encoding: utf-8 -*-
# stub: acts_as_follower 0.2.1 ruby lib
Gem::Specification.new do |s|
s.name = "acts_as_follower".freeze
s.version = "0.2.1"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Tom Cocca".freeze]
s.date = "2020-05-26"
s.description = "acts_as_follower is a Rubygem to allow any model to follow any other model. This is accomplished through a double polymorphic relationship on the Follow model. There is also built in support for blocking/un-blocking follow records. Main uses would be for Users to follow other Users or for Users to follow Books, etc\u2026 (Basically, to develop the type of follow system that GitHub has)".freeze
s.email = ["tom dot cocca at gmail dot com".freeze]
s.files = [".gitignore".freeze, ".travis.yml".freeze, "Gemfile".freeze, "MIT-LICENSE".freeze, "README.rdoc".freeze, "Rakefile".freeze, "acts_as_follower.gemspec".freeze, "init.rb".freeze, "lib/acts_as_follower.rb".freeze, "lib/acts_as_follower/follow_scopes.rb".freeze, "lib/acts_as_follower/followable.rb".freeze, "lib/acts_as_follower/follower.rb".freeze, "lib/acts_as_follower/follower_lib.rb".freeze, "lib/acts_as_follower/railtie.rb".freeze, "lib/acts_as_follower/version.rb".freeze, "lib/generators/USAGE".freeze, "lib/generators/acts_as_follower_generator.rb".freeze, "lib/generators/templates/migration.rb".freeze, "lib/generators/templates/model.rb".freeze, "test/README".freeze, "test/acts_as_followable_test.rb".freeze, "test/acts_as_follower_test.rb".freeze, "test/dummy30/Gemfile".freeze, "test/dummy30/Rakefile".freeze, "test/dummy30/app/models/application_record.rb".freeze, "test/dummy30/app/models/band.rb".freeze, "test/dummy30/app/models/band/punk.rb".freeze, "test/dummy30/app/models/band/punk/pop_punk.rb".freeze, "test/dummy30/app/models/custom_record.rb".freeze, "test/dummy30/app/models/some.rb".freeze, "test/dummy30/app/models/user.rb".freeze, "test/dummy30/config.ru".freeze, "test/dummy30/config/application.rb".freeze, "test/dummy30/config/boot.rb".freeze, "test/dummy30/config/database.yml".freeze, "test/dummy30/config/environment.rb".freeze, "test/dummy30/config/environments/development.rb".freeze, "test/dummy30/config/environments/test.rb".freeze, "test/dummy30/config/initializers/backtrace_silencers.rb".freeze, "test/dummy30/config/initializers/inflections.rb".freeze, "test/dummy30/config/initializers/secret_token.rb".freeze, "test/dummy30/config/initializers/session_store.rb".freeze, "test/dummy30/config/locales/en.yml".freeze, "test/dummy30/config/routes.rb".freeze, "test/factories/bands.rb".freeze, "test/factories/somes.rb".freeze, "test/factories/users.rb".freeze, "test/follow_test.rb".freeze, "test/schema.rb".freeze, "test/test_helper.rb".freeze]
s.homepage = "https://github.com/tcocca/acts_as_follower".freeze
s.licenses = ["MIT".freeze]
s.rubygems_version = "3.1.2".freeze
s.summary = "A Rubygem to add Follow functionality for ActiveRecord models".freeze
s.test_files = ["test/README".freeze, "test/acts_as_followable_test.rb".freeze, "test/acts_as_follower_test.rb".freeze, "test/dummy30/Gemfile".freeze, "test/dummy30/Rakefile".freeze, "test/dummy30/app/models/application_record.rb".freeze, "test/dummy30/app/models/band.rb".freeze, "test/dummy30/app/models/band/punk.rb".freeze, "test/dummy30/app/models/band/punk/pop_punk.rb".freeze, "test/dummy30/app/models/custom_record.rb".freeze, "test/dummy30/app/models/some.rb".freeze, "test/dummy30/app/models/user.rb".freeze, "test/dummy30/config.ru".freeze, "test/dummy30/config/application.rb".freeze, "test/dummy30/config/boot.rb".freeze, "test/dummy30/config/database.yml".freeze, "test/dummy30/config/environment.rb".freeze, "test/dummy30/config/environments/development.rb".freeze, "test/dummy30/config/environments/test.rb".freeze, "test/dummy30/config/initializers/backtrace_silencers.rb".freeze, "test/dummy30/config/initializers/inflections.rb".freeze, "test/dummy30/config/initializers/secret_token.rb".freeze, "test/dummy30/config/initializers/session_store.rb".freeze, "test/dummy30/config/locales/en.yml".freeze, "test/dummy30/config/routes.rb".freeze, "test/factories/bands.rb".freeze, "test/factories/somes.rb".freeze, "test/factories/users.rb".freeze, "test/follow_test.rb".freeze, "test/schema.rb".freeze, "test/test_helper.rb".freeze]
s.installed_by_version = "3.1.2" if s.respond_to? :installed_by_version
if s.respond_to? :specification_version then
s.specification_version = 4
end
if s.respond_to? :add_runtime_dependency then
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 4.0"])
s.add_development_dependency(%q<sqlite3>.freeze, [">= 0"])
s.add_development_dependency(%q<shoulda_create>.freeze, [">= 0"])
s.add_development_dependency(%q<shoulda>.freeze, [">= 3.5.0"])
s.add_development_dependency(%q<factory_girl>.freeze, [">= 4.2.0"])
s.add_development_dependency(%q<rails>.freeze, [">= 4.0"])
else
s.add_dependency(%q<activerecord>.freeze, [">= 4.0"])
s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
s.add_dependency(%q<shoulda_create>.freeze, [">= 0"])
s.add_dependency(%q<shoulda>.freeze, [">= 3.5.0"])
s.add_dependency(%q<factory_girl>.freeze, [">= 4.2.0"])
s.add_dependency(%q<rails>.freeze, [">= 4.0"])
end
end

View file

@ -0,0 +1 @@
require 'acts_as_follower'

View file

@ -0,0 +1,33 @@
require "acts_as_follower/version"
module ActsAsFollower
autoload :Follower, 'acts_as_follower/follower'
autoload :Followable, 'acts_as_follower/followable'
autoload :FollowerLib, 'acts_as_follower/follower_lib'
autoload :FollowScopes, 'acts_as_follower/follow_scopes'
def self.setup
@configuration ||= Configuration.new
yield @configuration if block_given?
end
def self.method_missing(method_name, *args, &block)
if method_name == :custom_parent_classes=
ActiveSupport::Deprecation.warn("Setting custom parent classes is deprecated and will be removed in future versions.")
end
@configuration.respond_to?(method_name) ?
@configuration.send(method_name, *args, &block) : super
end
class Configuration
attr_accessor :custom_parent_classes
def initialize
@custom_parent_classes = []
end
end
setup
require 'acts_as_follower/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
end

View file

@ -0,0 +1,45 @@
module ActsAsFollower #:nodoc:
module FollowScopes
# returns Follow records where follower is the record passed in.
def for_follower(follower)
where(follower_id: follower.id, follower_type: parent_class_name(follower))
end
# returns Follow records where followable is the record passed in.
def for_followable(followable)
where(followable_id: followable.id, followable_type: parent_class_name(followable))
end
# returns Follow records where follower_type is the record passed in.
def for_follower_type(follower_type)
where(follower_type: follower_type)
end
# returns Follow records where followeable_type is the record passed in.
def for_followable_type(followable_type)
where(followable_type: followable_type)
end
# returns Follow records from past 2 weeks with default parameter.
def recent(from)
where(["created_at > ?", (from || 2.weeks.ago).to_s(:db)])
end
# returns Follow records in descending order.
def descending
order("follows.created_at DESC")
end
# returns unblocked Follow records.
def unblocked
where(blocked: false)
end
# returns blocked Follow records.
def blocked
where(blocked: true)
end
end
end

View file

@ -0,0 +1,113 @@
module ActsAsFollower #:nodoc:
module Followable
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_followable
has_many :followings, as: :followable, dependent: :destroy, class_name: 'Follow'
include ActsAsFollower::Followable::InstanceMethods
include ActsAsFollower::FollowerLib
end
end
module InstanceMethods
# Returns the number of followers a record has.
def followers_count
self.followings.unblocked.count
end
# Returns the followers by a given type
def followers_by_type(follower_type, options={})
follows = follower_type.constantize.
joins(:follows).
where('follows.blocked' => false,
'follows.followable_id' => self.id,
'follows.followable_type' => parent_class_name(self),
'follows.follower_type' => follower_type)
if options.has_key?(:limit)
follows = follows.limit(options[:limit])
end
if options.has_key?(:includes)
follows = follows.includes(options[:includes])
end
follows
end
def followers_by_type_count(follower_type)
self.followings.unblocked.for_follower_type(follower_type).count
end
# Allows magic names on followers_by_type
# e.g. user_followers == followers_by_type('User')
# Allows magic names on followers_by_type_count
# e.g. count_user_followers == followers_by_type_count('User')
def method_missing(m, *args)
if m.to_s[/count_(.+)_followers/]
followers_by_type_count($1.singularize.classify)
elsif m.to_s[/(.+)_followers/]
followers_by_type($1.singularize.classify)
else
super
end
end
def respond_to?(m, include_private = false)
super || m.to_s[/count_(.+)_followers/] || m.to_s[/(.+)_followers/]
end
def blocked_followers_count
self.followings.blocked.count
end
# Returns the followings records scoped
def followers_scoped
self.followings.includes(:follower)
end
def followers(options={})
followers_scope = followers_scoped.unblocked
followers_scope = apply_options_to_scope(followers_scope, options)
followers_scope.to_a.collect{|f| f.follower}
end
def blocks(options={})
blocked_followers_scope = followers_scoped.blocked
blocked_followers_scope = apply_options_to_scope(blocked_followers_scope, options)
blocked_followers_scope.to_a.collect{|f| f.follower}
end
# Returns true if the current instance is followed by the passed record
# Returns false if the current instance is blocked by the passed record or no follow is found
def followed_by?(follower)
self.followings.unblocked.for_follower(follower).first.present?
end
def block(follower)
get_follow_for(follower) ? block_existing_follow(follower) : block_future_follow(follower)
end
def unblock(follower)
get_follow_for(follower).try(:delete)
end
def get_follow_for(follower)
self.followings.for_follower(follower).first
end
private
def block_future_follow(follower)
Follow.create(followable: self, follower: follower, blocked: true)
end
def block_existing_follow(follower)
get_follow_for(follower).block!
end
end
end
end

View file

@ -0,0 +1,112 @@
module ActsAsFollower #:nodoc:
module Follower
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_follower
has_many :follows, as: :follower, dependent: :destroy
include ActsAsFollower::Follower::InstanceMethods
include ActsAsFollower::FollowerLib
end
end
module InstanceMethods
# Returns true if this instance is following the object passed as an argument.
def following?(followable)
0 < Follow.unblocked.for_follower(self).for_followable(followable).count
end
# Returns the number of objects this instance is following.
def follow_count
Follow.unblocked.for_follower(self).count
end
# Creates a new follow record for this instance to follow the passed object.
# Does not allow duplicate records to be created.
def follow(followable)
if self != followable
params = {followable_id: followable.id, followable_type: parent_class_name(followable)}
self.follows.where(params).first_or_create!
end
end
# Deletes the follow record if it exists.
def stop_following(followable)
if follow = get_follow(followable)
follow.destroy
end
end
# returns the follows records to the current instance
def follows_scoped
self.follows.unblocked.includes(:followable)
end
# Returns the follow records related to this instance by type.
def follows_by_type(followable_type, options={})
follows_scope = follows_scoped.for_followable_type(followable_type)
follows_scope = apply_options_to_scope(follows_scope, options)
end
# Returns the follow records related to this instance with the followable included.
def all_follows(options={})
follows_scope = follows_scoped
follows_scope = apply_options_to_scope(follows_scope, options)
end
# Returns the actual records which this instance is following.
def all_following(options={})
all_follows(options).collect{ |f| f.followable }
end
# Returns the actual records of a particular type which this record is following.
def following_by_type(followable_type, options={})
followables = followable_type.constantize.
joins(:followings).
where('follows.blocked' => false,
'follows.follower_id' => self.id,
'follows.follower_type' => parent_class_name(self),
'follows.followable_type' => followable_type)
if options.has_key?(:limit)
followables = followables.limit(options[:limit])
end
if options.has_key?(:includes)
followables = followables.includes(options[:includes])
end
followables
end
def following_by_type_count(followable_type)
follows.unblocked.for_followable_type(followable_type).count
end
# Allows magic names on following_by_type
# e.g. following_users == following_by_type('User')
# Allows magic names on following_by_type_count
# e.g. following_users_count == following_by_type_count('User')
def method_missing(m, *args)
if m.to_s[/following_(.+)_count/]
following_by_type_count($1.singularize.classify)
elsif m.to_s[/following_(.+)/]
following_by_type($1.singularize.classify)
else
super
end
end
def respond_to?(m, include_private = false)
super || m.to_s[/following_(.+)_count/] || m.to_s[/following_(.+)/]
end
# Returns a follow record for the current instance and followable object.
def get_follow(followable)
self.follows.unblocked.for_followable(followable).first
end
end
end
end

View file

@ -0,0 +1,42 @@
module ActsAsFollower
module FollowerLib
private
DEFAULT_PARENTS = [ApplicationRecord, ActiveRecord::Base]
# Retrieves the parent class name if using STI.
def parent_class_name(obj)
unless parent_classes.include?(obj.class.superclass)
return obj.class.base_class.name
end
obj.class.name
end
def apply_options_to_scope(scope, options = {})
if options.has_key?(:limit)
scope = scope.limit(options[:limit])
end
if options.has_key?(:includes)
scope = scope.includes(options[:includes])
end
if options.has_key?(:joins)
scope = scope.joins(options[:joins])
end
if options.has_key?(:where)
scope = scope.where(options[:where])
end
if options.has_key?(:order)
scope = scope.order(options[:order])
end
scope
end
def parent_classes
return DEFAULT_PARENTS unless ActsAsFollower.custom_parent_classes.present?
ActiveSupport::Deprecation.warn("Setting custom parent classes is deprecated and will be removed in future versions.")
ActsAsFollower.custom_parent_classes + DEFAULT_PARENTS
end
end
end

View file

@ -0,0 +1,14 @@
require 'rails'
module ActsAsFollower
class Railtie < Rails::Railtie
initializer "acts_as_follower.active_record" do |app|
ActiveSupport.on_load :active_record do
include ActsAsFollower::Follower
include ActsAsFollower::Followable
end
end
end
end

View file

@ -0,0 +1,3 @@
module ActsAsFollower
VERSION = "0.2.1"
end

View file

@ -0,0 +1,5 @@
Description:
rails generate acts_as_follower
no need to specify a name after acts_as_follower as you can not change the model name from Follow
the acts_as_follower_migration file will be created in db/migrate

View file

@ -0,0 +1,30 @@
require 'rails/generators'
require 'rails/generators/migration'
class ActsAsFollowerGenerator < Rails::Generators::Base
include Rails::Generators::Migration
def self.source_root
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
end
# Implement the required interface for Rails::Generators::Migration.
# taken from https://github.com/rails/rails/blob/master/activerecord/lib/rails/generators/active_record.rb
def self.next_migration_number(dirname)
if ActiveRecord::Base.timestamped_migrations
Time.now.utc.strftime("%Y%m%d%H%M%S")
else
"%.3d" % (current_migration_number(dirname) + 1)
end
end
def create_migration_file
migration_template 'migration.rb', 'db/migrate/acts_as_follower_migration.rb'
end
def create_model
template "model.rb", File.join('app/models', "follow.rb")
end
end

View file

@ -0,0 +1,17 @@
class ActsAsFollowerMigration < ActiveRecord::Migration
def self.up
create_table :follows, force: true do |t|
t.references :followable, polymorphic: true, null: false
t.references :follower, polymorphic: true, null: false
t.boolean :blocked, default: false, null: false
t.timestamps
end
add_index :follows, ["follower_id", "follower_type"], name: "fk_follows"
add_index :follows, ["followable_id", "followable_type"], name: "fk_followables"
end
def self.down
drop_table :follows
end
end

View file

@ -0,0 +1,14 @@
class Follow < ActiveRecord::Base
extend ActsAsFollower::FollowerLib
extend ActsAsFollower::FollowScopes
# NOTE: Follows belong to the "followable" and "follower" interface
belongs_to :followable, polymorphic: true
belongs_to :follower, polymorphic: true
def block!
self.update_attribute(:blocked, true)
end
end

View file

@ -0,0 +1,24 @@
Testing
=======
Tests are written with Shoulda on top of Test::Unit and Factory Girl is used instead of fixtures. Tests are run using rake.
1. Clone your fork git locally.
2. Install the dependencies
$ bundle install
3. Run the tests:
rake test
Coverage
=======
Test coverage can be calculated using Rcov. Make sure you have the rcov gem installed.
Again in the acts_as_follower directory:
rake rcov:gen DB=sqlite3 # For sqlite
The coverage will now be available in the test/coverage directory.
rake rcov:clobber will delete the coverage directory.

View file

@ -0,0 +1,283 @@
require File.dirname(__FILE__) + '/test_helper'
class ActsAsFollowableTest < ActiveSupport::TestCase
context "instance methods" do
setup do
@sam = FactoryGirl.create(:sam)
end
should "be defined" do
assert @sam.respond_to?(:followers_count)
assert @sam.respond_to?(:followers)
assert @sam.respond_to?(:followed_by?)
end
end
context "acts_as_followable" do
setup do
@sam = FactoryGirl.create(:sam)
@jon = FactoryGirl.create(:jon)
@oasis = FactoryGirl.create(:oasis)
@metallica = FactoryGirl.create(:metallica)
@green_day = FactoryGirl.create(:green_day)
@blink_182 = FactoryGirl.create(:blink_182)
@sam.follow(@jon)
end
context "followers_count" do
should "return the number of followers" do
assert_equal 0, @sam.followers_count
assert_equal 1, @jon.followers_count
end
should "return the proper number of multiple followers" do
@bob = FactoryGirl.create(:bob)
@sam.follow(@bob)
assert_equal 0, @sam.followers_count
assert_equal 1, @jon.followers_count
assert_equal 1, @bob.followers_count
end
end
context "followers" do
should "return users" do
assert_equal [], @sam.followers
assert_equal [@sam], @jon.followers
end
should "return users (multiple followers)" do
@bob = FactoryGirl.create(:bob)
@sam.follow(@bob)
assert_equal [], @sam.followers
assert_equal [@sam], @jon.followers
assert_equal [@sam], @bob.followers
end
should "return users (multiple followers, complex)" do
@bob = FactoryGirl.create(:bob)
@sam.follow(@bob)
@jon.follow(@bob)
assert_equal [], @sam.followers
assert_equal [@sam], @jon.followers
assert_equal [@sam, @jon], @bob.followers
end
should "accept AR options" do
@bob = FactoryGirl.create(:bob)
@bob.follow(@jon)
assert_equal 1, @jon.followers(limit: 1).count
end
end
context "followed_by" do
should "return_follower_status" do
assert_equal true, @jon.followed_by?(@sam)
assert_equal false, @sam.followed_by?(@jon)
end
end
context "destroying a followable" do
setup do
@jon.destroy
end
should_change("follow count", by: -1) { Follow.count }
should_change("@sam.all_following.size", by: -1) { @sam.all_following.size }
end
context "get follow record" do
setup do
@bob = FactoryGirl.create(:bob)
@follow = @bob.follow(@sam)
end
should "return follow record" do
assert_equal @follow, @sam.get_follow_for(@bob)
end
should "return nil" do
assert_nil @sam.get_follow_for(@jon)
end
end
context "blocks" do
setup do
@bob = FactoryGirl.create(:bob)
@jon.block(@sam)
@jon.block(@bob)
end
should "accept AR options" do
assert_equal 1, @jon.blocks(limit: 1).count
end
end
context "blocking a follower" do
context "in my following list" do
setup do
@jon.block(@sam)
end
should "remove him from followers" do
assert_equal 0, @jon.followers_count
end
should "add him to the blocked followers" do
assert_equal 1, @jon.blocked_followers_count
end
should "not be able to follow again" do
@jon.follow(@sam)
assert_equal 0, @jon.followers_count
end
should "not be present when listing followers" do
assert_equal [], @jon.followers
end
should "be in the list of blocks" do
assert_equal [@sam], @jon.blocks
end
end
context "not in my following list" do
setup do
@sam.block(@jon)
end
should "add him to the blocked followers" do
assert_equal 1, @sam.blocked_followers_count
end
should "not be able to follow again" do
@sam.follow(@jon)
assert_equal 0, @sam.followers_count
end
should "not be present when listing followers" do
assert_equal [], @sam.followers
end
should "be in the list of blocks" do
assert_equal [@jon], @sam.blocks
end
end
end
context "unblocking a blocked follow" do
setup do
@jon.block(@sam)
@jon.unblock(@sam)
end
should "not include the unblocked user in the list of followers" do
assert_equal [], @jon.followers
end
should "remove him from the blocked followers" do
assert_equal 0, @jon.blocked_followers_count
assert_equal [], @jon.blocks
end
end
context "unblock a non-existent follow" do
setup do
@sam.stop_following(@jon)
@jon.unblock(@sam)
end
should "not be in the list of followers" do
assert_equal [], @jon.followers
end
should "not be in the blocked followers count" do
assert_equal 0, @jon.blocked_followers_count
end
should "not be in the blocks list" do
assert_equal [], @jon.blocks
end
end
context "followers_by_type" do
setup do
@sam.follow(@oasis)
@jon.follow(@oasis)
end
should "return the followers for given type" do
assert_equal [@sam], @jon.followers_by_type('User')
assert_equal [@sam, @jon], @oasis.followers_by_type('User')
end
should "not return block followers in the followers for a given type" do
@oasis.block(@jon)
assert_equal [@sam], @oasis.followers_by_type('User')
end
should "return the count for followers_by_type_count for a given type" do
assert_equal 1, @jon.followers_by_type_count('User')
assert_equal 2, @oasis.followers_by_type_count('User')
end
should "not count blocked follows in the count" do
@oasis.block(@sam)
assert_equal 1, @oasis.followers_by_type_count('User')
end
end
context "followers_with_sti" do
setup do
@sam.follow(@green_day)
@sam.follow(@blink_182)
end
should "return the followers for given type" do
assert_equal @sam.follows_by_type('Band').first.followable, @green_day.becomes(Band)
assert_equal @sam.follows_by_type('Band').second.followable, @blink_182.becomes(Band)
assert @green_day.followers_by_type('User').include?(@sam)
assert @blink_182.followers_by_type('User').include?(@sam)
end
end
context "method_missing" do
setup do
@sam.follow(@oasis)
@jon.follow(@oasis)
end
should "return the followers for given type" do
assert_equal [@sam], @jon.user_followers
assert_equal [@sam, @jon], @oasis.user_followers
end
should "not return block followers in the followers for a given type" do
@oasis.block(@jon)
assert_equal [@sam], @oasis.user_followers
end
should "return the count for followers_by_type_count for a given type" do
assert_equal 1, @jon.count_user_followers
assert_equal 2, @oasis.count_user_followers
end
should "not count blocked follows in the count" do
@oasis.block(@sam)
assert_equal 1, @oasis.count_user_followers
end
end
context "respond_to?" do
should "advertise that it responds to following methods" do
assert @oasis.respond_to?(:user_followers)
assert @oasis.respond_to?(:user_followers_count)
end
should "return false when called with a nonexistent method" do
assert (not @oasis.respond_to?(:foobar))
end
end
end
end

View file

@ -0,0 +1,224 @@
require File.dirname(__FILE__) + '/test_helper'
class ActsAsFollowerTest < ActiveSupport::TestCase
context "instance methods" do
setup do
@sam = FactoryGirl.create(:sam)
end
should "be defined" do
assert @sam.respond_to?(:following?)
assert @sam.respond_to?(:follow_count)
assert @sam.respond_to?(:follow)
assert @sam.respond_to?(:stop_following)
assert @sam.respond_to?(:follows_by_type)
assert @sam.respond_to?(:all_follows)
end
end
context "acts_as_follower" do
setup do
@sam = FactoryGirl.create(:sam)
@jon = FactoryGirl.create(:jon)
@oasis = FactoryGirl.create(:oasis)
@sam.follow(@jon)
@sam.follow(@oasis)
end
context "following" do
should "return following_status" do
assert_equal true, @sam.following?(@jon)
assert_equal false, @jon.following?(@sam)
end
should "return follow_count" do
assert_equal 2, @sam.follow_count
assert_equal 0, @jon.follow_count
end
end
context "follow a friend" do
setup do
@jon.follow(@sam)
end
should_change("Follow count", by: 1) { Follow.count }
should_change("@jon.follow_count", by: 1) { @jon.follow_count }
should "set the follower" do
assert_equal @jon, Follow.last.follower
end
should "set the followable" do
assert_equal @sam, Follow.last.followable
end
end
context "follow yourself" do
setup do
@jon.follow(@jon)
end
should_not_change("Follow count") { Follow.count }
should_not_change("@jon.follow_count") { @jon.follow_count }
should "not set the follower" do
assert_not_equal @jon, Follow.last.follower
end
should "not set the followable" do
assert_not_equal @jon, Follow.last.followable
end
end
context "stop_following" do
setup do
@sam.stop_following(@jon)
end
should_change("Follow count", by: -1) { Follow.count }
should_change("@sam.follow_count", by: -1) { @sam.follow_count }
end
context "follows" do
setup do
@band_follow = Follow.where("follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'Band'", @sam.id, @oasis.id).first
@user_follow = Follow.where("follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'User'", @sam.id, @jon.id).first
end
context "follows_by_type" do
should "only return requested follows" do
assert_equal [@band_follow], @sam.follows_by_type('Band')
assert_equal [@user_follow], @sam.follows_by_type('User')
end
should "accept AR options" do
@metallica = FactoryGirl.create(:metallica)
@sam.follow(@metallica)
assert_equal 1, @sam.follows_by_type('Band', limit: 1).count
end
end
context "following_by_type_count" do
should "return the count of the requested type" do
@metallica = FactoryGirl.create(:metallica)
@sam.follow(@metallica)
assert_equal 2, @sam.following_by_type_count('Band')
assert_equal 1, @sam.following_by_type_count('User')
assert_equal 0, @jon.following_by_type_count('Band')
@jon.block(@sam)
assert_equal 0, @sam.following_by_type_count('User')
end
end
context "all_follows" do
should "return all follows" do
assert_equal 2, @sam.all_follows.size
assert @sam.all_follows.include?(@band_follow)
assert @sam.all_follows.include?(@user_follow)
assert_equal [], @jon.all_follows
end
should "accept AR options" do
assert_equal 1, @sam.all_follows(limit: 1).count
end
end
end
context "all_following" do
should "return the actual follow records" do
assert_equal 2, @sam.all_following.size
assert @sam.all_following.include?(@oasis)
assert @sam.all_following.include?(@jon)
assert_equal [], @jon.all_following
end
should "accept AR limit option" do
assert_equal 1, @sam.all_following(limit: 1).count
end
should "accept AR where option" do
assert_equal 1, @sam.all_following(where: { id: @oasis.id }).count
end
end
context "following_by_type" do
should "return only requested records" do
assert_equal [@oasis], @sam.following_by_type('Band')
assert_equal [@jon], @sam.following_by_type('User')
end
should "accept AR options" do
@metallica = FactoryGirl.create(:metallica)
@sam.follow(@metallica)
assert_equal 1, @sam.following_by_type('Band', limit: 1).to_a.size
end
end
context "method_missing" do
should "call following_by_type" do
assert_equal [@oasis], @sam.following_bands
assert_equal [@jon], @sam.following_users
end
should "call following_by_type_count" do
@metallica = FactoryGirl.create(:metallica)
@sam.follow(@metallica)
assert_equal 2, @sam.following_bands_count
assert_equal 1, @sam.following_users_count
assert_equal 0, @jon.following_bands_count
@jon.block(@sam)
assert_equal 0, @sam.following_users_count
end
should "raise on no method" do
assert_raises (NoMethodError){ @sam.foobar }
end
end
context "respond_to?" do
should "advertise that it responds to following methods" do
assert @sam.respond_to?(:following_users)
assert @sam.respond_to?(:following_users_count)
end
should "return false when called with a nonexistent method" do
assert (not @sam.respond_to?(:foobar))
end
end
context "destroying follower" do
setup do
@jon.destroy
end
should_change("Follow.count", by: -1) { Follow.count }
should_change("@sam.follow_count", by: -1) { @sam.follow_count }
end
context "blocked by followable" do
setup do
@jon.block(@sam)
end
should "return following_status" do
assert_equal false, @sam.following?(@jon)
end
should "return follow_count" do
assert_equal 1, @sam.follow_count
end
should "not return record of the blocked follows" do
assert_equal 1, @sam.all_follows.size
assert !@sam.all_follows.include?(@user_follow)
assert !@sam.all_following.include?(@jon)
assert_equal [], @sam.following_by_type('User')
assert_equal [], @sam.follows_by_type('User')
assert_equal [], @sam.following_users
end
end
end
end

View file

@ -0,0 +1 @@
gem 'rails', '~>3.0.10'

View file

@ -0,0 +1,7 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require 'rake'
Dummy::Application.load_tasks

View file

@ -0,0 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end

View file

@ -0,0 +1,4 @@
class Band < ApplicationRecord
validates_presence_of :name
acts_as_followable
end

View file

@ -0,0 +1,4 @@
class Band::Punk < Band
validates_presence_of :name
acts_as_followable
end

View file

@ -0,0 +1,4 @@
class Band::Punk::PopPunk < Band::Punk
validates_presence_of :name
acts_as_followable
end

View file

@ -0,0 +1,3 @@
class CustomRecord < ActiveRecord::Base
self.abstract_class = true
end

View file

@ -0,0 +1,5 @@
class Some < CustomRecord
validates_presence_of :name
acts_as_follower
acts_as_followable
end

View file

@ -0,0 +1,5 @@
class User < ApplicationRecord
validates_presence_of :name
acts_as_follower
acts_as_followable
end

View file

@ -0,0 +1,4 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Dummy::Application

View file

@ -0,0 +1,42 @@
require File.expand_path('../boot', __FILE__)
require "active_model/railtie"
require "active_record/railtie"
Bundler.require
require "acts_as_follower"
module Dummy
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# JavaScript files you want as :defaults (application.js is always included).
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
end
end

View file

@ -0,0 +1,10 @@
require 'rubygems'
gemfile = File.expand_path('../../../../Gemfile', __FILE__)
if File.exist?(gemfile)
ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup
end
$:.unshift File.expand_path('../../../../lib', __FILE__)

View file

@ -0,0 +1,7 @@
test:
adapter: sqlite3
database: ':memory:'
development:
adapter: sqlite3
database: ':memory:'

View file

@ -0,0 +1,5 @@
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
Dummy::Application.initialize!

View file

@ -0,0 +1,19 @@
Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
end

View file

@ -0,0 +1,20 @@
Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
end

View file

@ -0,0 +1,7 @@
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!

View file

@ -0,0 +1,10 @@
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end

View file

@ -0,0 +1,7 @@
# Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Dummy::Application.config.secret_token = '7b0ce915dc4c2ee60581c2769798abb5e4078292ad23670fc8d728953fc13aec19863558873234816b58a54f6a35be58b2b0a26749a7dfddcd2f02ee82d7e94f'

View file

@ -0,0 +1,8 @@
# Be sure to restart your server when you modify this file.
Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Dummy::Application.config.session_store :active_record_store

View file

@ -0,0 +1,5 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"

View file

@ -0,0 +1,2 @@
Dummy::Application.routes.draw do
end

View file

@ -0,0 +1,17 @@
FactoryGirl.define do
factory :oasis, class: Band do |b|
b.name 'Oasis'
end
factory :metallica, class: Band do |b|
b.name 'Metallica'
end
factory :green_day, :class => Band::Punk do |b|
b.name 'Green Day'
end
factory :blink_182, :class => Band::Punk::PopPunk do |b|
b.name 'Blink 182'
end
end

View file

@ -0,0 +1,9 @@
FactoryGirl.define do
factory :daddy, :class => Some do |b|
b.name 'Daddy'
end
factory :mommy, :class => Some do |b|
b.name 'Mommy'
end
end

View file

@ -0,0 +1,13 @@
FactoryGirl.define do
factory :jon, class: User do |u|
u.name 'Jon'
end
factory :sam, class: User do |u|
u.name 'Sam'
end
factory :bob, class: User do |u|
u.name 'Bob'
end
end

View file

@ -0,0 +1,28 @@
require File.dirname(__FILE__) + '/test_helper'
class FollowTest < ActiveSupport::TestCase
# Replace with real tests
def test_assert_true_should_be_true
assert true
end
context "configuration with setters" do
should "contain custom parents" do
ActsAsFollower.custom_parent_classes = [CustomRecord]
assert_equal [CustomRecord], ActsAsFollower.custom_parent_classes
end
end
context "#setup" do
should "contain custom parents via setup" do
ActsAsFollower.setup do |c|
c.custom_parent_classes = [CustomRecord]
end
assert_equal [CustomRecord], ActsAsFollower.custom_parent_classes
end
end
end

View file

@ -0,0 +1,25 @@
ActiveRecord::Schema.define version: 0 do
create_table :follows, force: true do |t|
t.integer "followable_id", null: false
t.string "followable_type", null: false
t.integer "follower_id", null: false
t.string "follower_type", null: false
t.boolean "blocked", default: false, null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table :users, force: true do |t|
t.column :name, :string
end
create_table :bands, force: true do |t|
t.column :name, :string
end
create_table :somes, :force => true do |t|
t.column :name, :string
end
end

View file

@ -0,0 +1,18 @@
# Configure Rails Envinronment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../dummy30/config/environment.rb", __FILE__)
require "rails/test_help"
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
ActiveRecord::Migration.verbose = false
load(File.dirname(__FILE__) + '/schema.rb')
require File.dirname(__FILE__) + '/../lib/generators/templates/model.rb'
require 'shoulda'
require 'shoulda_create'
require 'factory_girl'
ActiveSupport::TestCase.extend(ShouldaCreate)
FactoryGirl.find_definitions

BIN
vendor/cache/addressable-2.7.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/administrate-0.13.0.gem vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/cache/ahoy_email-1.1.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/algorithmia-1.1.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/amazing_print-1.1.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/ancestry-3.0.7.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/approvals-0.0.24.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/arel-9.0.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/ast-2.4.0.gem vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/cache/aws-eventstream-1.1.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/aws-partitions-1.314.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/aws-sdk-core-3.95.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/aws-sdk-lambda-1.41.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/aws-sigv4-1.1.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/aws_cf_signer-0.1.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/axiom-types-0.1.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/bcrypt-3.1.13.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/benchmark-ips-2.7.2.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/better_errors-2.7.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/better_html-1.0.14.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/bindex-0.8.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/binding_of_caller-0.8.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/blazer-2.2.2.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/bootsnap-1.4.6.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/brakeman-4.8.2.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/browser-4.0.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/buffer-0.1.3.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/buftok-0.2.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/builder-3.2.4.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/bullet-6.1.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/bundler-audit-0.6.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/byebug-11.1.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/capybara-3.32.1.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/carrierwave-2.1.0.gem vendored Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more