impressionist2 1.5.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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.rdoc +82 -0
- data/Gemfile +26 -0
- data/LICENSE.txt +20 -0
- data/README.md +250 -0
- data/Rakefile +34 -0
- data/app/controllers/impressionist_controller.rb +146 -0
- data/app/models/impression.rb +2 -0
- data/app/models/impressionist/bots.rb +1468 -0
- data/app/models/impressionist/impressionable.rb +62 -0
- data/gemfiles/rails32.gemfile +30 -0
- data/gemfiles/rails40.gemfile +30 -0
- data/gemfiles/rails50.gemfile +30 -0
- data/impressionist2.gemspec +23 -0
- data/lib/generators/active_record/impressionist_generator.rb +22 -0
- data/lib/generators/active_record/templates/create_impressions_table.rb +32 -0
- data/lib/generators/impressionist_generator.rb +13 -0
- data/lib/generators/mongo_mapper/impressionist_generator.rb +8 -0
- data/lib/generators/mongoid/impressionist_generator.rb +8 -0
- data/lib/generators/templates/impression.rb +8 -0
- data/lib/impressionist/bots.rb +21 -0
- data/lib/impressionist/controllers/mongoid/impressionist_controller.rb +10 -0
- data/lib/impressionist/counter_cache.rb +73 -0
- data/lib/impressionist/engine.rb +30 -0
- data/lib/impressionist/is_impressionable.rb +23 -0
- data/lib/impressionist/load.rb +11 -0
- data/lib/impressionist/models/active_record/impression.rb +14 -0
- data/lib/impressionist/models/active_record/impressionist/impressionable.rb +12 -0
- data/lib/impressionist/models/mongo_mapper/impression.rb +18 -0
- data/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb +21 -0
- data/lib/impressionist/models/mongoid/impression.rb +25 -0
- data/lib/impressionist/models/mongoid/impressionist/impressionable.rb +28 -0
- data/lib/impressionist/rails_toggle.rb +26 -0
- data/lib/impressionist/setup_association.rb +49 -0
- data/lib/impressionist/update_counters.rb +69 -0
- data/lib/impressionist/version.rb +3 -0
- data/lib/impressionist.rb +12 -0
- data/logo.png +0 -0
- data/tests/README +11 -0
- data/tests/spec/minitest_helper.rb +4 -0
- data/tests/spec/rails_toggle_spec.rb +38 -0
- data/tests/spec/setup_association_spec.rb +56 -0
- data/tests/test_app/.gitignore +18 -0
- data/tests/test_app/.rspec +1 -0
- data/tests/test_app/Gemfile +51 -0
- data/tests/test_app/README +256 -0
- data/tests/test_app/README.rdoc +261 -0
- data/tests/test_app/Rakefile +7 -0
- data/tests/test_app/app/assets/images/rails.png +0 -0
- data/tests/test_app/app/assets/javascripts/application.js +13 -0
- data/tests/test_app/app/assets/stylesheets/application.css +13 -0
- data/tests/test_app/app/controllers/application_controller.rb +8 -0
- data/tests/test_app/app/controllers/articles_controller.rb +18 -0
- data/tests/test_app/app/controllers/dummy_controller.rb +8 -0
- data/tests/test_app/app/controllers/posts_controller.rb +23 -0
- data/tests/test_app/app/controllers/profiles_controller.rb +14 -0
- data/tests/test_app/app/controllers/widgets_controller.rb +12 -0
- data/tests/test_app/app/helpers/application_helper.rb +2 -0
- data/tests/test_app/app/mailers/.gitkeep +0 -0
- data/tests/test_app/app/models/.gitkeep +0 -0
- data/tests/test_app/app/models/article.rb +3 -0
- data/tests/test_app/app/models/dummy.rb +7 -0
- data/tests/test_app/app/models/post.rb +3 -0
- data/tests/test_app/app/models/profile.rb +6 -0
- data/tests/test_app/app/models/user.rb +3 -0
- data/tests/test_app/app/models/widget.rb +3 -0
- data/tests/test_app/app/views/articles/index.html.erb +1 -0
- data/tests/test_app/app/views/articles/show.html.erb +1 -0
- data/tests/test_app/app/views/dummy/index.html.erb +0 -0
- data/tests/test_app/app/views/layouts/application.html.erb +14 -0
- data/tests/test_app/app/views/posts/edit.html.erb +0 -0
- data/tests/test_app/app/views/posts/index.html.erb +0 -0
- data/tests/test_app/app/views/posts/show.html.erb +0 -0
- data/tests/test_app/app/views/profiles/show.html.erb +3 -0
- data/tests/test_app/app/views/widgets/index.html.erb +0 -0
- data/tests/test_app/app/views/widgets/new.html.erb +0 -0
- data/tests/test_app/app/views/widgets/show.html.erb +0 -0
- data/tests/test_app/config/application.rb +59 -0
- data/tests/test_app/config/boot.rb +6 -0
- data/tests/test_app/config/cucumber.yml +8 -0
- data/tests/test_app/config/database.yml +30 -0
- data/tests/test_app/config/environment.rb +5 -0
- data/tests/test_app/config/environments/development.rb +37 -0
- data/tests/test_app/config/environments/pg_test.rb +35 -0
- data/tests/test_app/config/environments/production.rb +67 -0
- data/tests/test_app/config/environments/test.rb +37 -0
- data/tests/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/tests/test_app/config/initializers/impression.rb +8 -0
- data/tests/test_app/config/initializers/inflections.rb +15 -0
- data/tests/test_app/config/initializers/mime_types.rb +5 -0
- data/tests/test_app/config/initializers/secret_token.rb +7 -0
- data/tests/test_app/config/initializers/session_store.rb +8 -0
- data/tests/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/tests/test_app/config/locales/en.yml +5 -0
- data/tests/test_app/config/routes.rb +4 -0
- data/tests/test_app/config.ru +4 -0
- data/tests/test_app/db/migrate/20110201153144_create_articles.rb +13 -0
- data/tests/test_app/db/migrate/20110210205028_create_posts.rb +13 -0
- data/tests/test_app/db/migrate/20111127184039_create_widgets.rb +15 -0
- data/tests/test_app/db/migrate/20130719024021_create_impressions_table.rb +32 -0
- data/tests/test_app/db/migrate/20150207135825_create_profiles.rb +10 -0
- data/tests/test_app/db/migrate/20150207140310_create_friendly_id_slugs.rb +18 -0
- data/tests/test_app/db/schema.rb +80 -0
- data/tests/test_app/db/seeds.rb +7 -0
- data/tests/test_app/lib/assets/.gitkeep +0 -0
- data/tests/test_app/lib/tasks/.gitkeep +0 -0
- data/tests/test_app/lib/tasks/cucumber.rake +53 -0
- data/tests/test_app/log/.gitkeep +0 -0
- data/tests/test_app/public/404.html +26 -0
- data/tests/test_app/public/422.html +26 -0
- data/tests/test_app/public/500.html +25 -0
- data/tests/test_app/public/favicon.ico +0 -0
- data/tests/test_app/public/images/rails.png +0 -0
- data/tests/test_app/public/index.html +241 -0
- data/tests/test_app/public/javascripts/application.js +2 -0
- data/tests/test_app/public/javascripts/controls.js +965 -0
- data/tests/test_app/public/javascripts/dragdrop.js +974 -0
- data/tests/test_app/public/javascripts/effects.js +1123 -0
- data/tests/test_app/public/javascripts/prototype.js +6001 -0
- data/tests/test_app/public/javascripts/rails.js +175 -0
- data/tests/test_app/public/robots.txt +5 -0
- data/tests/test_app/public/stylesheets/.gitkeep +0 -0
- data/tests/test_app/script/cucumber +10 -0
- data/tests/test_app/script/rails +6 -0
- data/tests/test_app/spec/controllers/articles_controller_spec.rb +76 -0
- data/tests/test_app/spec/controllers/dummy_controller_spec.rb +11 -0
- data/tests/test_app/spec/controllers/impressionist_uniqueness_spec.rb +396 -0
- data/tests/test_app/spec/controllers/posts_controller_spec.rb +28 -0
- data/tests/test_app/spec/controllers/widgets_controller_spec.rb +91 -0
- data/tests/test_app/spec/fixtures/articles.yml +3 -0
- data/tests/test_app/spec/fixtures/impressions.yml +43 -0
- data/tests/test_app/spec/fixtures/posts.yml +3 -0
- data/tests/test_app/spec/fixtures/profiles.yml +4 -0
- data/tests/test_app/spec/fixtures/widgets.yml +4 -0
- data/tests/test_app/spec/initializers/initializers_spec.rb +20 -0
- data/tests/test_app/spec/models/bots_spec.rb +27 -0
- data/tests/test_app/spec/models/counter_caching_spec.rb +51 -0
- data/tests/test_app/spec/models/model_spec.rb +70 -0
- data/tests/test_app/spec/rails_generators/rails_generators_spec.rb +23 -0
- data/tests/test_app/spec/spec_helper.rb +43 -0
- data/upgrade_migrations/version_0_3_0.rb +27 -0
- data/upgrade_migrations/version_0_4_0.rb +9 -0
- metadata +314 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
module Impressionist
|
2
|
+
module Impressionable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
attr_accessor :impressionist_cache_options
|
7
|
+
|
8
|
+
DEFAULT_CACHE ||= {
|
9
|
+
:counter_cache => false,
|
10
|
+
:column_name => :impressions_count,
|
11
|
+
:unique => false
|
12
|
+
}
|
13
|
+
|
14
|
+
def impressionist_counter_cache_options
|
15
|
+
@impressionist_cache_options ||= {}
|
16
|
+
@impressionist_cache_options.reverse_merge!(DEFAULT_CACHE)
|
17
|
+
end
|
18
|
+
|
19
|
+
# asks impressionable entity whether or not it is counter_caching
|
20
|
+
def impressionist_counter_caching?
|
21
|
+
impressionist_counter_cache_options[:counter_cache]
|
22
|
+
end
|
23
|
+
|
24
|
+
def counter_caching?
|
25
|
+
::ActiveSupport::Deprecation.warn("#counter_caching? is deprecated; please use #impressionist_counter_caching? instead")
|
26
|
+
impressionist_counter_caching?
|
27
|
+
end
|
28
|
+
|
29
|
+
end # end of ClassMethods
|
30
|
+
|
31
|
+
def impressionist_count(options={})
|
32
|
+
# Uses these options as defaults unless overridden in options hash
|
33
|
+
options.reverse_merge!(:filter => :request_hash, :start_date => nil, :end_date => Time.now)
|
34
|
+
|
35
|
+
# If a start_date is provided, finds impressions between then and the end_date. Otherwise returns all impressions
|
36
|
+
imps = options[:start_date].blank? ? impressions : impressions.where("created_at >= ? and created_at <= ?", options[:start_date], options[:end_date])
|
37
|
+
|
38
|
+
if options[:message]
|
39
|
+
imps = imps.where("impressions.message = ?", options[:message])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Count all distinct impressions unless the :all filter is provided.
|
43
|
+
distinct = options[:filter] != :all
|
44
|
+
if Rails::VERSION::MAJOR >= 4
|
45
|
+
distinct ? imps.select(options[:filter]).distinct.count : imps.count
|
46
|
+
else
|
47
|
+
distinct ? imps.count(options[:filter], :distinct => true) : imps.count
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_impressionist_counter_cache
|
52
|
+
slave = Impressionist::UpdateCounters.new(self)
|
53
|
+
slave.update
|
54
|
+
end
|
55
|
+
|
56
|
+
def impressionable?
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rake', '>= 0.9'
|
4
|
+
gem 'rdoc', '>= 2.4.2'
|
5
|
+
|
6
|
+
platforms :jruby do
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
8
|
+
gem 'jdbc-sqlite3'
|
9
|
+
gem 'jruby-openssl'
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :ruby, :mswin, :mingw do
|
13
|
+
gem 'sqlite3'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem 'capybara', '>= 2.0.3'
|
18
|
+
gem 'minitest'
|
19
|
+
gem 'minitest-rails'
|
20
|
+
gem 'rails', '~> 3.2.15'
|
21
|
+
gem 'rspec-rails', '~> 2.14.0'
|
22
|
+
gem 'simplecov'
|
23
|
+
gem 'systemu'
|
24
|
+
gem 'friendly_id', '~> 4.0.9'
|
25
|
+
|
26
|
+
# test/unit has been removed by default in Ruby 2.2.x+
|
27
|
+
gem 'test-unit'
|
28
|
+
end
|
29
|
+
|
30
|
+
gemspec :path => '../'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rake', '>= 0.9'
|
4
|
+
gem 'rdoc', '>= 2.4.2'
|
5
|
+
|
6
|
+
platforms :jruby do
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
8
|
+
gem 'jdbc-sqlite3'
|
9
|
+
gem 'jruby-openssl'
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :ruby, :mswin, :mingw do
|
13
|
+
gem 'sqlite3'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem 'capybara', '>= 2.0.3'
|
18
|
+
gem 'minitest'
|
19
|
+
gem 'minitest-rails'
|
20
|
+
gem 'rails', '~> 4.0.1'
|
21
|
+
gem 'rspec-rails', '~> 2.14.0'
|
22
|
+
gem 'simplecov'
|
23
|
+
gem 'systemu'
|
24
|
+
gem 'friendly_id', '~> 5.1.0'
|
25
|
+
|
26
|
+
# test/unit has been removed by default in Ruby 2.2.x+
|
27
|
+
gem 'test-unit'
|
28
|
+
end
|
29
|
+
|
30
|
+
gemspec :path => '../'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rake', '>= 0.9'
|
4
|
+
gem 'rdoc', '>= 2.4.2'
|
5
|
+
|
6
|
+
platforms :jruby do
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
8
|
+
gem 'jdbc-sqlite3'
|
9
|
+
gem 'jruby-openssl'
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :ruby, :mswin, :mingw do
|
13
|
+
gem 'sqlite3'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem 'capybara', '>= 2.0.3'
|
18
|
+
gem 'minitest'
|
19
|
+
gem 'minitest-rails'
|
20
|
+
gem 'rails', '~> 5.0.0'
|
21
|
+
gem 'rspec-rails', '~> 2.14.0'
|
22
|
+
gem 'simplecov'
|
23
|
+
gem 'systemu'
|
24
|
+
gem 'friendly_id', '~> 5.1.0'
|
25
|
+
|
26
|
+
# test/unit has been removed by default in Ruby 2.2.x+
|
27
|
+
gem 'test-unit'
|
28
|
+
end
|
29
|
+
|
30
|
+
gemspec :path => '../'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'impressionist/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'impressionist2'
|
7
|
+
s.version = Impressionist::VERSION.dup
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.licenses = ['MIT']
|
10
|
+
s.summary = 'Easy way to log impressions'
|
11
|
+
s.email = 'john.mcaliley@gmail.com'
|
12
|
+
s.homepage = 'http://github.com/charlotte-ruby/impressionist'
|
13
|
+
s.description = 'Log impressions from controller actions or from a model'
|
14
|
+
s.authors = ['johnmcaliley']
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- tests/**/*`.split("\n")
|
18
|
+
s.require_path = 'lib'
|
19
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
|
20
|
+
|
21
|
+
s.add_dependency 'nokogiri', '~> 1.6'
|
22
|
+
s.add_development_dependency 'bundler', '~> 1.0'
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Generators
|
3
|
+
class ImpressionistGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
6
|
+
|
7
|
+
# FIX, why is this implementing rails behaviour?
|
8
|
+
def self.next_migration_number(dirname)
|
9
|
+
sleep 1
|
10
|
+
if ActiveRecord::Base.timestamped_migrations
|
11
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
12
|
+
else
|
13
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_migration_file
|
18
|
+
migration_template 'create_impressions_table.rb', 'db/migrate/create_impressions_table.rb'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class CreateImpressionsTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :impressions, :force => true do |t|
|
4
|
+
t.string :impressionable_type
|
5
|
+
t.integer :impressionable_id
|
6
|
+
t.integer :user_id
|
7
|
+
t.string :controller_name
|
8
|
+
t.string :action_name
|
9
|
+
t.string :view_name
|
10
|
+
t.string :request_hash
|
11
|
+
t.string :ip_address
|
12
|
+
t.string :session_hash
|
13
|
+
t.text :message
|
14
|
+
t.text :referrer
|
15
|
+
t.text :params
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
add_index :impressions, [:impressionable_type, :message, :impressionable_id], :name => "impressionable_type_message_index", :unique => false, :length => {:message => 255 }
|
19
|
+
add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false
|
20
|
+
add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false
|
21
|
+
add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false
|
22
|
+
add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false
|
23
|
+
add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false
|
24
|
+
add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false
|
25
|
+
add_index :impressions, [:impressionable_type, :impressionable_id, :params], :name => "poly_params_request_index", :unique => false
|
26
|
+
add_index :impressions, :user_id
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.down
|
30
|
+
drop_table :impressions
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Impressionist
|
2
|
+
module Generators
|
3
|
+
class ImpressionistGenerator < Rails::Generators::Base
|
4
|
+
hook_for :orm
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
def copy_config_file
|
8
|
+
template 'impression.rb', 'config/initializers/impression.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Use this hook to configure impressionist parameters
|
2
|
+
#Impressionist.setup do |config|
|
3
|
+
# Define ORM. Could be :active_record (default), :mongo_mapper or :mongoid
|
4
|
+
# config.orm = :active_record
|
5
|
+
#end
|
6
|
+
|
7
|
+
<% orm = options.orm.match(/mongoid|active_record|mongomapper/) %>
|
8
|
+
<%= "Impressionist.orm = :#{options.orm}" if String === options.orm %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'net/http'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module Impressionist
|
6
|
+
module Bots
|
7
|
+
LIST_URL = "http://www.user-agents.org/allagents.xml"
|
8
|
+
def self.consume
|
9
|
+
Timeout.timeout(4) do
|
10
|
+
response = Net::HTTP.get(URI.parse(LIST_URL))
|
11
|
+
doc = Nokogiri::XML(response)
|
12
|
+
list = []
|
13
|
+
doc.xpath('//user-agent').each do |agent|
|
14
|
+
type = agent.xpath("Type").text
|
15
|
+
list << agent.xpath("String").text.gsub("<","<") if ["R","S"].include?(type) #gsub hack for badly formatted data
|
16
|
+
end
|
17
|
+
list
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
ImpressionistController::InstanceMethods.send(:define_method, :direct_create_statement) do |query_params={}|
|
2
|
+
# creates a statment hash that contains default values for creating an impression.
|
3
|
+
# if :impressionable_id is a valid ObjectId then convert it into one
|
4
|
+
base = (defined? Moped) ? Moped::BSON : BSON
|
5
|
+
query_params.reverse_merge!(
|
6
|
+
:impressionable_type => controller_path.singularize.camelize,
|
7
|
+
:impressionable_id=> !base::ObjectId.legal?(params[:id]) ? params[:id] : base::ObjectId.from_string(params[:id])
|
8
|
+
)
|
9
|
+
associative_create_statement(query_params)
|
10
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Impressionist
|
2
|
+
module CounterCache
|
3
|
+
|
4
|
+
attr_reader :impressionable_class, :entity
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# A valid impression must
|
9
|
+
# have a valid impressionable class
|
10
|
+
# be counter_caching
|
11
|
+
# have a record saved in the db
|
12
|
+
# then it should give it a try
|
13
|
+
def impressionable_counter_cache_updatable?
|
14
|
+
updatable? && impressionable_try
|
15
|
+
end
|
16
|
+
|
17
|
+
def updatable?
|
18
|
+
valid_impressionable_class? && impressionable_find
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_impressionable_class?
|
22
|
+
set_impressionable_class && counter_caching?
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_impressionable_class
|
26
|
+
klass = self.impressionable_type || false
|
27
|
+
@impressionable_class = klass.
|
28
|
+
to_s.safe_constantize || false
|
29
|
+
end
|
30
|
+
|
31
|
+
def impressionist_log(str, mode=:error)
|
32
|
+
Rails.logger.send(mode.to_s, str)
|
33
|
+
end
|
34
|
+
|
35
|
+
# receives an entity(instance of a Model) and then tries to update
|
36
|
+
# counter_cache column
|
37
|
+
# entity is a impressionable instance model
|
38
|
+
def impressionable_try
|
39
|
+
entity.try(:update_impressionist_counter_cache)
|
40
|
+
end
|
41
|
+
|
42
|
+
def impressionable_find
|
43
|
+
exeception_rescuer {
|
44
|
+
@entity = impressionable_class.find(self.impressionable_id)
|
45
|
+
}
|
46
|
+
@entity
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def counter_caching?
|
51
|
+
impressionable_class.
|
52
|
+
impressionist_counter_caching?
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Returns false, as it is only handling one exeception
|
57
|
+
# It would make updatable to fail thereafter it would not try
|
58
|
+
# to update cache_counter
|
59
|
+
def exeception_rescuer
|
60
|
+
begin
|
61
|
+
yield
|
62
|
+
rescue ActiveRecord::RecordNotFound
|
63
|
+
exeception_to_log
|
64
|
+
false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def exeception_to_log
|
69
|
+
impressionist_log("Couldn't find Widget with id=#{self.impressionable_id}")
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Impressionist
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
attr_accessor :orm
|
4
|
+
|
5
|
+
initializer 'impressionist.model' do |app|
|
6
|
+
@orm = Impressionist.orm
|
7
|
+
include_orm
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
initializer 'impressionist.controller' do
|
12
|
+
require "impressionist/controllers/mongoid/impressionist_controller.rb" if orm == :mongoid.to_s
|
13
|
+
|
14
|
+
ActiveSupport.on_load(:action_controller) do
|
15
|
+
include ImpressionistController::InstanceMethods
|
16
|
+
extend ImpressionistController::ClassMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def include_orm
|
24
|
+
require "#{root}/app/models/impressionist/impressionable.rb"
|
25
|
+
require "impressionist/models/#{orm}/impression.rb"
|
26
|
+
require "impressionist/models/#{orm}/impressionist/impressionable.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Impressionist
|
2
|
+
module IsImpressionable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def is_impressionable(options={})
|
7
|
+
define_association
|
8
|
+
@impressionist_cache_options = options
|
9
|
+
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def define_association
|
16
|
+
has_many(:impressions,
|
17
|
+
:as => :impressionable,
|
18
|
+
:dependent => :destroy)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Responsability
|
2
|
+
# * logs an error if imps_id and imps_type can not be found
|
3
|
+
# * asks updatable? whether it may or may not be updated
|
4
|
+
|
5
|
+
class Impression < ActiveRecord::Base
|
6
|
+
|
7
|
+
include Impressionist::CounterCache
|
8
|
+
|
9
|
+
# sets belongs_to and attr_accessible depending on Rails version
|
10
|
+
Impressionist::SetupAssociation.new(self).set
|
11
|
+
|
12
|
+
store :params
|
13
|
+
after_save :impressionable_counter_cache_updatable?
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Impression
|
2
|
+
include MongoMapper::Document
|
3
|
+
|
4
|
+
key :impressionable_type, String
|
5
|
+
key :impressionable_id, String
|
6
|
+
key :user_id, String
|
7
|
+
key :controller_name, String
|
8
|
+
key :action_name, String
|
9
|
+
key :view_name, String
|
10
|
+
key :request_hash, String
|
11
|
+
key :ip_address, String
|
12
|
+
key :session_hash, String
|
13
|
+
key :message, String
|
14
|
+
key :referrer, String
|
15
|
+
timestamps!
|
16
|
+
|
17
|
+
belongs_to :impressionable, :polymorphic=>true
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MongoMapper::Document.plugin Impressionist::Impressionable
|
2
|
+
|
3
|
+
module Impressionist
|
4
|
+
module Impressionable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def is_impressionable(options={})
|
10
|
+
many(:impressions,
|
11
|
+
:as => :impressionable,
|
12
|
+
:dependent => :destroy)
|
13
|
+
|
14
|
+
@impressionist_cache_options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
##
|
2
|
+
# see active_record/impression.rb
|
3
|
+
# same doc applies to here
|
4
|
+
class Impression
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Timestamps
|
7
|
+
|
8
|
+
include Impressionist::CounterCache
|
9
|
+
Impressionist::SetupAssociation.new(self).set
|
10
|
+
|
11
|
+
field :impressionable_id, type: BSON::ObjectId
|
12
|
+
field :impressionable_type
|
13
|
+
field :user_id
|
14
|
+
field :controller_name
|
15
|
+
field :action_name
|
16
|
+
field :view_name
|
17
|
+
field :request_hash
|
18
|
+
field :ip_address
|
19
|
+
field :session_hash
|
20
|
+
field :message
|
21
|
+
field :referrer
|
22
|
+
|
23
|
+
after_save :impressionable_counter_cache_updatable?
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Impressionist
|
2
|
+
module Impressionable
|
3
|
+
|
4
|
+
# extends AS::Concern
|
5
|
+
include Impressionist::IsImpressionable
|
6
|
+
|
7
|
+
# Overides impressionist_count in order to provide mongoid compability
|
8
|
+
def impressionist_count(options={})
|
9
|
+
|
10
|
+
# Uses these options as defaults unless overridden in options hash
|
11
|
+
options.reverse_merge!(:filter => :request_hash, :start_date => nil, :end_date => Time.now)
|
12
|
+
|
13
|
+
# If a start_date is provided, finds impressions between then and the end_date.
|
14
|
+
# Otherwise returns all impressions
|
15
|
+
imps = options[:start_date].blank? ? impressions :
|
16
|
+
impressions.between(created_at: options[:start_date]..options[:end_date])
|
17
|
+
|
18
|
+
|
19
|
+
# Count all distinct impressions unless the :all filter is provided
|
20
|
+
distinct = options[:filter] != :all
|
21
|
+
distinct ? imps.where(options[:filter].ne => nil).distinct(options[:filter]).count : imps.count
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Mongoid::Document.
|
28
|
+
send(:include, Impressionist::Impressionable)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Impressionist
|
2
|
+
# Responsibility
|
3
|
+
# Toggles between rails > 3.1 < 4
|
4
|
+
# In order to make attr_accessible available in a rails app < 4
|
5
|
+
|
6
|
+
class RailsToggle
|
7
|
+
# decides where or not to include attr_accessible
|
8
|
+
def should_include?
|
9
|
+
supported_by_rails? && (not using_strong_parameters?)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def using_strong_parameters?
|
15
|
+
defined?(StrongParameters)
|
16
|
+
end
|
17
|
+
|
18
|
+
# returns false if rails >= 4
|
19
|
+
# true if rails < 4
|
20
|
+
def supported_by_rails?
|
21
|
+
::Rails::VERSION::MAJOR.to_i < 4
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Impressionist
|
2
|
+
# Impressionist::SetupAssociation.new(entity).set
|
3
|
+
class SetupAssociation
|
4
|
+
def initialize(receiver)
|
5
|
+
@receiver = receiver
|
6
|
+
end
|
7
|
+
|
8
|
+
# True or False
|
9
|
+
# Note toggle returns false if rails >= 4
|
10
|
+
def include_attr_acc?
|
11
|
+
toggle && make_accessible
|
12
|
+
end
|
13
|
+
|
14
|
+
def define_belongs_to
|
15
|
+
receiver.belongs_to(:impressionable, :polymorphic => true)
|
16
|
+
end
|
17
|
+
|
18
|
+
def set
|
19
|
+
define_belongs_to
|
20
|
+
include_attr_acc?
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
attr_reader :receiver, :toggle
|
25
|
+
|
26
|
+
def make_accessible
|
27
|
+
receiver.
|
28
|
+
attr_accessible(:impressionable_type,
|
29
|
+
:impressionable_id,
|
30
|
+
:controller_name,
|
31
|
+
:request_hash,
|
32
|
+
:session_hash,
|
33
|
+
:action_name,
|
34
|
+
:ip_address,
|
35
|
+
:view_name,
|
36
|
+
:referrer,
|
37
|
+
:message,
|
38
|
+
:user_id,
|
39
|
+
:params)
|
40
|
+
end
|
41
|
+
|
42
|
+
def toggle
|
43
|
+
t = RailsToggle.new
|
44
|
+
t.should_include?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|