module GroupedScope class SelfGroupping attr_reader :proxy_owner, :reflection delegate :quote_value, :columns_hash, :to => :proxy_class [].methods.each do |m| unless m =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to|proxy_/ delegate m, :to => :grouped_proxy end end def initialize(proxy_owner) raise NoGroupIdError.new(proxy_owner) unless proxy_owner.class.column_names.include?('group_id') @proxy_owner = proxy_owner end def blank? proxy_owner.group_id.blank? end def present? !blank? end def ids grouped_scoped_ids.map(&primary_key.to_sym) end def ids_sql Arel.sql(grouped_scoped_ids.to_sql) end def quoted_ids ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',') end def with_reflection(reflection) @reflection = reflection yield ensure @reflection = nil end def respond_to?(method, include_private=false) super || proxy_class.grouped_reflections[method].present? || grouped_proxy.respond_to?(method, include_private) end protected def primary_key reflection ? reflection.association_primary_key : proxy_class.primary_key end def arel_group_id arel_table['group_id'] end def arel_primary_key arel_table[primary_key] end def arel_table reflection ? Arel::Table.new(reflection.table_name) : proxy_class.arel_table end def grouped_proxy @grouped_proxy ||= grouped_scoped end def all_grouped? proxy_owner.all_grouped? rescue false end def grouped_scoped return proxy_class.scoped if all_grouped? proxy_class.where present? ? arel_group_id.eq(proxy_owner.group_id) : arel_primary_key.eq(proxy_owner.id) end def grouped_scoped_ids grouped_scoped.select(arel_primary_key) end def proxy_class proxy_owner.class end private def method_missing(method, *args) if proxy_class.grouped_reflections[method] if block_given? proxy_owner.send(:"grouped_scope_#{method}", *args) { |*block_args| yield(*block_args) } else proxy_owner.send(:"grouped_scope_#{method}", *args) end elsif grouped_proxy.respond_to?(method) if block_given? grouped_proxy.send(method, *args) { |*block_args| yield(*block_args) } else grouped_proxy.send(method, *args) end else super end end end end