module Rails3Finders

Public Class Methods

except(*options) click to toggle source

returns a new scope, having removed the options mentioned does not support extended scopes

# File lib/fake_arel/rails_3_finders.rb, line 65
def self.except(*options)
  # include is renamed to includes in Rails 3
  includes = options.delete(:includes)
  options << :include if includes
  
  new_options = (scope(:find) || {}).reject { |k, v| options.include?(k) }
  with_exclusive_scope(:find => new_options) { scoped }
end
fakearel_destroy() click to toggle source
# File lib/fake_arel/rails_3_finders.rb, line 98
def self.fakearel_destroy
  self.destroy_all(:id => self.scoped({}).select(:id).map(&:id))
end
fakearel_find_each(options = {:batch_size => 1000}) { |entry| ... } click to toggle source
# File lib/fake_arel/rails_3_finders.rb, line 89
def self.fakearel_find_each(options = {:batch_size => 1000}, &block)
  count = self.scoped({}).count
  offset = 0
  while offset < count
    self.scoped(:limit => options[:batch_size], :offset => offset).each { |entry| yield entry }
    offset += options[:batch_size]
  end
end
included(base) click to toggle source
# File lib/fake_arel/rails_3_finders.rb, line 3
def self.included(base)
  base.class_eval do

    # the default named scopes
    named_scope :offset, lambda {|offset| {:offset => offset}}
    named_scope :limit, lambda {|limit| {:limit => limit}}
    named_scope :includes, lambda { |*includes| { :include => includes }}
    named_scope :order, lambda {|*order| {:order => order.flatten.join(',') }}
    named_scope :joins, lambda {|*join| {:joins => join } if join[0]}
    named_scope :from, lambda {|*from| {:from => from.flatten.join(',') }}
    named_scope :having, lambda {|*having| {:having => having }}
    named_scope :group, lambda {|*group| {:group => group.flatten.join(',') }}
    named_scope :readonly, lambda {|readonly| {:readonly => readonly }}
    named_scope :lock, lambda {|*lock| lock = [true] if lock.empty?; {:lock => lock.first }}

    def self.select(value = Proc.new)
      if block_given?
        all.select {|*block_args| value.call(*block_args) }
      else
        self.scoped(:select => Array.wrap(value).join(','))
      end
    end

    __where_fn = lambda do |*where|
      if where.is_a?(Array) and where.size == 1
        {:conditions => where.first}
      else
        {:conditions => where}
      end
    end

    named_scope :where, __where_fn

    __or_fn = lambda do |*scopes|
      where = []
      joins = []
      includes = []

      # for some reason, flatten is actually executing the scope
      scopes = scopes[0] if scopes.size == 1
      scopes.each do |s|
        scope = s.proxy_scope
        s = s.proxy_options
        begin
          where << scope.merge_conditions(s[:conditions])
        rescue NoMethodError
          # I am ActiveRecord::Base. Only my subclasses define merge_conditions:
          where << subclasses.first.merge_conditions(s[:conditions])
        end
        #where << merge_conditions(s[:conditions])
        joins << s[:joins] unless s[:joins].nil?
        includes << s[:include] unless s[:include].nil?
      end
      scoped = self
      scoped = scoped.includes(includes.uniq.flatten) unless includes.blank?
      scoped = scoped.joins(joins.uniq.flatten) unless joins.blank?
      scoped.where(where.join(" OR "))
    end
    named_scope :or, __or_fn

    # returns a new scope, having removed the options mentioned
    # does *not* support extended scopes
    def self.except(*options)
      # include is renamed to includes in Rails 3
      includes = options.delete(:includes)
      options << :include if includes

      new_options = (scope(:find) || {}).reject { |k, v| options.include?(k) }
      with_exclusive_scope(:find => new_options) { scoped }
    end

    # returns a new scope, with just the order replaced
    # does *not* support extended scopes
    def self.reorder(*order)
      new_options = (scope(:find) || {}).dup
      new_options[:order] = order.flatten.join(',')
      with_exclusive_scope(:find =>new_options) { scoped }
    end
  
    def self.pluck(column)
      new_options = (scope(:find) || {}).dup
      new_options[:select] = "#{quoted_table_name}.#{column}"
      new_options.delete(:include)
      with_exclusive_scope(:find => new_options) { all.map(&column) }
    end

    def self.fakearel_find_each(options = {:batch_size => 1000}, &block)
      count = self.scoped({}).count
      offset = 0
      while offset < count
        self.scoped(:limit => options[:batch_size], :offset => offset).each { |entry| yield entry }
        offset += options[:batch_size]
      end
    end

    def self.fakearel_destroy
      self.destroy_all(:id => self.scoped({}).select(:id).map(&:id))
    end

    # allow defining scopes Rails 3 style (scope, not named_scope)
    # scope is still a Rails 2 method, so we have to call the correct method
    # depending on the argument types
    def self.scope_with_named_scope(*args, &block)
      if args.length == 2
        case args[1]
          when String, Symbol
            scope_without_named_scope(*args)
          else
            named_scope *args, &block
        end
      else
        scope_without_named_scope(*args)
      end
    end
    class << self
      alias_method_chain :scope, :named_scope
    end
  end
end
pluck(column) click to toggle source
# File lib/fake_arel/rails_3_finders.rb, line 82
def self.pluck(column)
  new_options = (scope(:find) || {}).dup
  new_options[:select] = "#{quoted_table_name}.#{column}"
  new_options.delete(:include)
  with_exclusive_scope(:find => new_options) { all.map(&column) }
end
reorder(*order) click to toggle source

returns a new scope, with just the order replaced does not support extended scopes

# File lib/fake_arel/rails_3_finders.rb, line 76
def self.reorder(*order)
  new_options = (scope(:find) || {}).dup
  new_options[:order] = order.flatten.join(',')
  with_exclusive_scope(:find =>new_options) { scoped }
end
scope_with_named_scope(*args, &block) click to toggle source

allow defining scopes Rails 3 style (scope, not named_scope) scope is still a Rails 2 method, so we have to call the correct method depending on the argument types

# File lib/fake_arel/rails_3_finders.rb, line 105
def self.scope_with_named_scope(*args, &block)
  if args.length == 2
    case args[1]
      when String, Symbol
        scope_without_named_scope(*args)
      else
        named_scope *args, &block
    end
  else
    scope_without_named_scope(*args)
  end
end
select(value = Proc.new) click to toggle source
# File lib/fake_arel/rails_3_finders.rb, line 18
def self.select(value = Proc.new)
  if block_given?
    all.select {|*block_args| value.call(*block_args) }
  else
    self.scoped(:select => Array.wrap(value).join(','))
  end
end