Permalink
Browse files

Mongoid functionality working for Mongoid 3.0, haven't got to grips w…

…ith the tests yet, so will push those in next commit
  • Loading branch information...
1 parent bdd7a05 commit 7ab364c7eb0469a323269b2927fe9070064575d7 @jgwmaxwell committed Jul 11, 2012
View
8 lib/generators/mongoid/impressionist_generator.rb
@@ -0,0 +1,8 @@
+module Mongoid
+ module Generators
+ class ImpressionistGenerator < Rails::Generators::Base
+ # Empty for now, need it for generating the config file without
+ # triggering other ORM's generators.
+ end
+ end
+end
View
2 lib/generators/templates/impression.rb
@@ -1,5 +1,5 @@
# Use this hook to configure impressionist parameters
Impressionist.setup do |config|
- # Define ORM. Could be :active_record (default) and :mongo_mapper
+ # Define ORM. Could be :active_record (default), :mongo_mapper or :mongoid
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

Just for sake of completeness, not at all Mongoid propaganda ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
# config.orm = :active_record
end
View
9 lib/impressionist/controllers/mongoid/impressionist_controller.rb
@@ -0,0 +1,9 @@
+ImpressionistController::InstanceMethods.send(:define_method, :direct_create_statement) do |query_params={}|
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

Mongoid needs the Id of the Polymorphic record to be supplied as a Moped::BSON::ObjectId. In order to do this without rewriting the whole of the controller module, redefining this method seemed to be the best method. I've only required this file if :mongoid is selected, so for MongoMapper and AR the original code remains unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # creates a statment hash that contains default values for creating an impression.
+ # if :impressionable_id is a valid ObjectId then convert it into one
+ query_params.reverse_merge!(
+ :impressionable_type => controller_name.singularize.camelize,
+ :impressionable_id=> !Moped::BSON::ObjectId.legal?(params[:id]) ? params[:id] : Moped::BSON::ObjectId.from_string(params[:id])
+ )
+ associative_create_statement(query_params)
+end
View
7 lib/impressionist/engine.rb
@@ -13,10 +13,17 @@ class Engine < Rails::Engine
require "impressionist/models/mongo_mapper/impression.rb"
require "impressionist/models/mongo_mapper/impressionist/impressionable.rb"
MongoMapper::Document.plugin Impressionist::Impressionable
+ elsif Impressionist.orm == :mongoid
+ require 'impressionist/models/mongoid/impression.rb'
+ require 'impressionist/models/mongoid/impressionist/impressionable.rb'
+ Mongoid::Document.send(:include, Impressionist::Impressionable)
end
end
initializer 'impressionist.controller' do
+ if Impressionist.orm == :mongoid
+ require 'impressionist/controllers/mongoid/impressionist_controller.rb'
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

This file fixes the #direct_create_statement method with one that Mongoid can cope with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
ActiveSupport.on_load(:action_controller) do
include ImpressionistController::InstanceMethods
extend ImpressionistController::ClassMethods
View
32 lib/impressionist/models/mongoid/impression.rb
@@ -0,0 +1,32 @@
+class Impression
+ include Mongoid::Document
+ include Mongoid::Timestamps
+
+ attr_accessible :impressionable_type, :impressionable_field, :impressionable_id, :user_id,
+ :controller_name, :action_name, :view_name, :request_hash, :ip_address,
+ :session_hash, :message, :referrer
+
+ belongs_to :impressionable, polymorphic: true
+
+ field :user_id
+ field :controller_name
+ field :action_name
+ field :view_name
+ field :request_hash
+ field :ip_address
+ field :session_hash
+ field :message
+ field :referrer
+
+ set_callback(:create, :after) do |doc|
+ unless impressionable_id.nil?
+ impressionable_class = doc.impressionable_type.constantize
+
+ if impressionable_class.impressionist_counter_cache_options
+ resource = impressionable_class.find(doc.impressionable_id)
+ resource.try(:update_impressionist_counter_cache)
+ end
+ end
+ end
+
+end
View
52 lib/impressionist/models/mongoid/impressionist/impressionable.rb
@@ -0,0 +1,52 @@
+module Impressionist
+ module Impressionable
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def is_impressionable(options={})
+ has_many :impressions, as: :impressionable, dependent: :destroy
+ @impressionist_cache_options = options[:counter_cache]
+ if !@impressionist_cache_options.nil?
+ opts = impressionist_counter_cache_options
+ field opts[:column_name], type: Integer
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

If there is a counter_cache, declare the field for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+ end
+
+ def impressionist_counter_cache_options
+ if @impressionist_cache_options
+ options = { :column_name => :impressions_count, :unique => false }
+ options.merge!(@impressionist_cache_options) if @impressionist_cache_options.is_a?(Hash)
+ options
+ end
+ end
+
+ def impressionist_counter_caching?
+ impressionist_counter_cache_options.present?
+ end
+
+ def counter_caching?
+ ::ActiveSupport::Deprecation.warn("#counter_caching? is deprecated; please use #impressionist_counter_caching? instead")
+ impressionist_counter_caching?
+ end
+ end
+
+ def impressionable?
+ true
+ end
+
+ def impressionist_count(options={})
+ options.reverse_merge!(:filter=>:request_hash, :start_date=>nil, :end_date=>Time.now)
+ imps = options[:start_date].blank? ? impressions : impressions.between(created_at: options[:start_date]..options[:end_date])
+ options[:filter] == :all ? imps.count : imps.where(options[:filter].ne => nil).count
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

Mongoid doesn't run #count the same way as AR, so defining the filter to check for existence, and the time check to be a simple Range

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+
+ def update_impressionist_counter_cache
+ cache_options = self.class.impressionist_counter_cache_options
+ column_name = cache_options[:column_name].to_sym
+ count = cache_options[:unique] ? impressionist_count(:filter => :ip_address) : impressionist_count
+ old_count = send(column_name) || 0
+ self.inc(column_name, (count - old_count))
@jgwmaxwell
Owner
jgwmaxwell added a line comment Jul 11, 2012

Use Model#inc atomic update here as it is fast and accurate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+
+ end
+end

0 comments on commit 7ab364c

Please sign in to comment.