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.
Files changed (146) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +26 -0
  5. data/CHANGELOG.rdoc +82 -0
  6. data/Gemfile +26 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +250 -0
  9. data/Rakefile +34 -0
  10. data/app/controllers/impressionist_controller.rb +146 -0
  11. data/app/models/impression.rb +2 -0
  12. data/app/models/impressionist/bots.rb +1468 -0
  13. data/app/models/impressionist/impressionable.rb +62 -0
  14. data/gemfiles/rails32.gemfile +30 -0
  15. data/gemfiles/rails40.gemfile +30 -0
  16. data/gemfiles/rails50.gemfile +30 -0
  17. data/impressionist2.gemspec +23 -0
  18. data/lib/generators/active_record/impressionist_generator.rb +22 -0
  19. data/lib/generators/active_record/templates/create_impressions_table.rb +32 -0
  20. data/lib/generators/impressionist_generator.rb +13 -0
  21. data/lib/generators/mongo_mapper/impressionist_generator.rb +8 -0
  22. data/lib/generators/mongoid/impressionist_generator.rb +8 -0
  23. data/lib/generators/templates/impression.rb +8 -0
  24. data/lib/impressionist/bots.rb +21 -0
  25. data/lib/impressionist/controllers/mongoid/impressionist_controller.rb +10 -0
  26. data/lib/impressionist/counter_cache.rb +73 -0
  27. data/lib/impressionist/engine.rb +30 -0
  28. data/lib/impressionist/is_impressionable.rb +23 -0
  29. data/lib/impressionist/load.rb +11 -0
  30. data/lib/impressionist/models/active_record/impression.rb +14 -0
  31. data/lib/impressionist/models/active_record/impressionist/impressionable.rb +12 -0
  32. data/lib/impressionist/models/mongo_mapper/impression.rb +18 -0
  33. data/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb +21 -0
  34. data/lib/impressionist/models/mongoid/impression.rb +25 -0
  35. data/lib/impressionist/models/mongoid/impressionist/impressionable.rb +28 -0
  36. data/lib/impressionist/rails_toggle.rb +26 -0
  37. data/lib/impressionist/setup_association.rb +49 -0
  38. data/lib/impressionist/update_counters.rb +69 -0
  39. data/lib/impressionist/version.rb +3 -0
  40. data/lib/impressionist.rb +12 -0
  41. data/logo.png +0 -0
  42. data/tests/README +11 -0
  43. data/tests/spec/minitest_helper.rb +4 -0
  44. data/tests/spec/rails_toggle_spec.rb +38 -0
  45. data/tests/spec/setup_association_spec.rb +56 -0
  46. data/tests/test_app/.gitignore +18 -0
  47. data/tests/test_app/.rspec +1 -0
  48. data/tests/test_app/Gemfile +51 -0
  49. data/tests/test_app/README +256 -0
  50. data/tests/test_app/README.rdoc +261 -0
  51. data/tests/test_app/Rakefile +7 -0
  52. data/tests/test_app/app/assets/images/rails.png +0 -0
  53. data/tests/test_app/app/assets/javascripts/application.js +13 -0
  54. data/tests/test_app/app/assets/stylesheets/application.css +13 -0
  55. data/tests/test_app/app/controllers/application_controller.rb +8 -0
  56. data/tests/test_app/app/controllers/articles_controller.rb +18 -0
  57. data/tests/test_app/app/controllers/dummy_controller.rb +8 -0
  58. data/tests/test_app/app/controllers/posts_controller.rb +23 -0
  59. data/tests/test_app/app/controllers/profiles_controller.rb +14 -0
  60. data/tests/test_app/app/controllers/widgets_controller.rb +12 -0
  61. data/tests/test_app/app/helpers/application_helper.rb +2 -0
  62. data/tests/test_app/app/mailers/.gitkeep +0 -0
  63. data/tests/test_app/app/models/.gitkeep +0 -0
  64. data/tests/test_app/app/models/article.rb +3 -0
  65. data/tests/test_app/app/models/dummy.rb +7 -0
  66. data/tests/test_app/app/models/post.rb +3 -0
  67. data/tests/test_app/app/models/profile.rb +6 -0
  68. data/tests/test_app/app/models/user.rb +3 -0
  69. data/tests/test_app/app/models/widget.rb +3 -0
  70. data/tests/test_app/app/views/articles/index.html.erb +1 -0
  71. data/tests/test_app/app/views/articles/show.html.erb +1 -0
  72. data/tests/test_app/app/views/dummy/index.html.erb +0 -0
  73. data/tests/test_app/app/views/layouts/application.html.erb +14 -0
  74. data/tests/test_app/app/views/posts/edit.html.erb +0 -0
  75. data/tests/test_app/app/views/posts/index.html.erb +0 -0
  76. data/tests/test_app/app/views/posts/show.html.erb +0 -0
  77. data/tests/test_app/app/views/profiles/show.html.erb +3 -0
  78. data/tests/test_app/app/views/widgets/index.html.erb +0 -0
  79. data/tests/test_app/app/views/widgets/new.html.erb +0 -0
  80. data/tests/test_app/app/views/widgets/show.html.erb +0 -0
  81. data/tests/test_app/config/application.rb +59 -0
  82. data/tests/test_app/config/boot.rb +6 -0
  83. data/tests/test_app/config/cucumber.yml +8 -0
  84. data/tests/test_app/config/database.yml +30 -0
  85. data/tests/test_app/config/environment.rb +5 -0
  86. data/tests/test_app/config/environments/development.rb +37 -0
  87. data/tests/test_app/config/environments/pg_test.rb +35 -0
  88. data/tests/test_app/config/environments/production.rb +67 -0
  89. data/tests/test_app/config/environments/test.rb +37 -0
  90. data/tests/test_app/config/initializers/backtrace_silencers.rb +7 -0
  91. data/tests/test_app/config/initializers/impression.rb +8 -0
  92. data/tests/test_app/config/initializers/inflections.rb +15 -0
  93. data/tests/test_app/config/initializers/mime_types.rb +5 -0
  94. data/tests/test_app/config/initializers/secret_token.rb +7 -0
  95. data/tests/test_app/config/initializers/session_store.rb +8 -0
  96. data/tests/test_app/config/initializers/wrap_parameters.rb +14 -0
  97. data/tests/test_app/config/locales/en.yml +5 -0
  98. data/tests/test_app/config/routes.rb +4 -0
  99. data/tests/test_app/config.ru +4 -0
  100. data/tests/test_app/db/migrate/20110201153144_create_articles.rb +13 -0
  101. data/tests/test_app/db/migrate/20110210205028_create_posts.rb +13 -0
  102. data/tests/test_app/db/migrate/20111127184039_create_widgets.rb +15 -0
  103. data/tests/test_app/db/migrate/20130719024021_create_impressions_table.rb +32 -0
  104. data/tests/test_app/db/migrate/20150207135825_create_profiles.rb +10 -0
  105. data/tests/test_app/db/migrate/20150207140310_create_friendly_id_slugs.rb +18 -0
  106. data/tests/test_app/db/schema.rb +80 -0
  107. data/tests/test_app/db/seeds.rb +7 -0
  108. data/tests/test_app/lib/assets/.gitkeep +0 -0
  109. data/tests/test_app/lib/tasks/.gitkeep +0 -0
  110. data/tests/test_app/lib/tasks/cucumber.rake +53 -0
  111. data/tests/test_app/log/.gitkeep +0 -0
  112. data/tests/test_app/public/404.html +26 -0
  113. data/tests/test_app/public/422.html +26 -0
  114. data/tests/test_app/public/500.html +25 -0
  115. data/tests/test_app/public/favicon.ico +0 -0
  116. data/tests/test_app/public/images/rails.png +0 -0
  117. data/tests/test_app/public/index.html +241 -0
  118. data/tests/test_app/public/javascripts/application.js +2 -0
  119. data/tests/test_app/public/javascripts/controls.js +965 -0
  120. data/tests/test_app/public/javascripts/dragdrop.js +974 -0
  121. data/tests/test_app/public/javascripts/effects.js +1123 -0
  122. data/tests/test_app/public/javascripts/prototype.js +6001 -0
  123. data/tests/test_app/public/javascripts/rails.js +175 -0
  124. data/tests/test_app/public/robots.txt +5 -0
  125. data/tests/test_app/public/stylesheets/.gitkeep +0 -0
  126. data/tests/test_app/script/cucumber +10 -0
  127. data/tests/test_app/script/rails +6 -0
  128. data/tests/test_app/spec/controllers/articles_controller_spec.rb +76 -0
  129. data/tests/test_app/spec/controllers/dummy_controller_spec.rb +11 -0
  130. data/tests/test_app/spec/controllers/impressionist_uniqueness_spec.rb +396 -0
  131. data/tests/test_app/spec/controllers/posts_controller_spec.rb +28 -0
  132. data/tests/test_app/spec/controllers/widgets_controller_spec.rb +91 -0
  133. data/tests/test_app/spec/fixtures/articles.yml +3 -0
  134. data/tests/test_app/spec/fixtures/impressions.yml +43 -0
  135. data/tests/test_app/spec/fixtures/posts.yml +3 -0
  136. data/tests/test_app/spec/fixtures/profiles.yml +4 -0
  137. data/tests/test_app/spec/fixtures/widgets.yml +4 -0
  138. data/tests/test_app/spec/initializers/initializers_spec.rb +20 -0
  139. data/tests/test_app/spec/models/bots_spec.rb +27 -0
  140. data/tests/test_app/spec/models/counter_caching_spec.rb +51 -0
  141. data/tests/test_app/spec/models/model_spec.rb +70 -0
  142. data/tests/test_app/spec/rails_generators/rails_generators_spec.rb +23 -0
  143. data/tests/test_app/spec/spec_helper.rb +43 -0
  144. data/upgrade_migrations/version_0_3_0.rb +27 -0
  145. data/upgrade_migrations/version_0_4_0.rb +9 -0
  146. 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
+ module MongoMapper
2
+ module Generators
3
+ class ImpressionistGenerator < Rails::Generators::Base
4
+ # Empty for now, need it for generating the config file without
5
+ # triggering other ORM's generators.
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Mongoid
2
+ module Generators
3
+ class ImpressionistGenerator < Rails::Generators::Base
4
+ # Empty for now, need it for generating the config file without
5
+ # triggering other ORM's generators.
6
+ end
7
+ end
8
+ 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("&lt;","<") 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,11 @@
1
+ require 'impressionist/setup_association'
2
+
3
+ require 'impressionist/counter_cache'
4
+
5
+ require 'impressionist/update_counters'
6
+
7
+ require 'impressionist/rails_toggle'
8
+
9
+ require 'impressionist/is_impressionable'
10
+
11
+ require 'impressionist/engine'
@@ -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,12 @@
1
+ module Impressionist
2
+
3
+ module Impressionable
4
+
5
+ # extends AS::Concern
6
+ include Impressionist::IsImpressionable
7
+ end
8
+
9
+ end
10
+
11
+ ActiveRecord::Base.
12
+ send(:include, Impressionist::Impressionable)
@@ -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
+