# https://rails.lighthouseapp.com/projects/8994/tickets/5182-activerecordcalculations-returns-incorrect-data-when-grouping-by-multiple-fields module ActsAsJoinable def self.models unless @models if defined?(Rails) @models = Dir[Dir.pwd + "/app/models/*.rb"].collect { |f| File.basename f, '.rb' } else @models = [] end end @models end def self.models=(value) @models = value end def self.included(base) base.extend ClassMethods end module ClassMethods def joinable? false end def acts_as_joinable_on(*args, &block) args << block if joinable? write_inheritable_attribute(:acts_as_joinable_config, args) else write_inheritable_attribute(:acts_as_joinable_config, args) class_inheritable_reader(:acts_as_joinable_config) class_eval do def self.joinable? true end include ActsAsJoinable::Core end end end # Group.count_joins(:as => :parent, :conditions) def count_joins(options = {}) relationship = options.delete(:as) || :parent conditions = options[:conditions] || {} conditions["#{relationship.to_s}_type".to_sym] = ([self.name] + (self.send(:subclasses) - self.included_modules).map(&:name)).flatten.uniq group = options[:group] || "#{relationship}_id" Relationship.count(:conditions => conditions, :group => group) end def acts_as_joinable acts_as_joinable_on end def joinable acts_as_joinable_on end def joins_many(*args, &block) acts_as_joinable_on(*args, &block) end def joins(*args, &block) acts_as_joinable_on(*args, &block) end def joins_one(*args, &block) options = args.extract_options! options[:limit] = 1 args << options acts_as_joinable_on(*args, &block) end def acts_as_relationship belongs_to :parent, :polymorphic => true belongs_to :child, :polymorphic => true # validates_uniqueness_of :parent_id, :scope => [:parent_type, :child_id] # validates_uniqueness_of :child_id, :scope => [:child_type, :parent_id] # ActsAsJoinable.models.each do |m| # belongs_to "parent_#{m}".intern, :foreign_key => 'parent_id', :class_name => m.camelize # belongs_to "child_#{m}".intern, :foreign_key => 'child_id', :class_name => m.camelize # end end end end ActiveRecord::Base.send(:include, ActsAsJoinable) if defined?(ActiveRecord::Base) Dir["#{File.dirname(__FILE__)}/../app/models/*"].each { |c| require c if File.extname(c) == ".rb" } Dir["#{File.dirname(__FILE__)}/acts_as_joinable/*"].each { |c| require c if File.extname(c) == ".rb" }