class ActiveHash::Relation
Attributes
all_records[RW]
klass[RW]
query_hash[RW]
records_dirty[RW]
Public Class Methods
new(klass, all_records, query_hash = nil)
click to toggle source
# File lib/active_hash/relation.rb, line 10 def initialize(klass, all_records, query_hash = nil) self.klass = klass self.all_records = all_records self.query_hash = query_hash self.records_dirty = false self end
Public Instance Methods
all(options = {})
click to toggle source
# File lib/active_hash/relation.rb, line 26 def all(options = {}) if options.has_key?(:conditions) where(options[:conditions]) else where({}) end end
count()
click to toggle source
# File lib/active_hash/relation.rb, line 65 def count length end
find(id = nil, *args, &block)
click to toggle source
# File lib/active_hash/relation.rb, line 42 def find(id = nil, *args, &block) case id when :all all when :first all(*args).first when Array id.map { |i| find(i) } when nil raise RecordNotFound.new("Couldn't find #{klass.name} without an ID") unless block_given? records.find(&block) # delegate to Enumerable#find if a block is given else find_by_id(id) || begin raise RecordNotFound.new("Couldn't find #{klass.name} with ID=#{id}") end end end
find_by(options)
click to toggle source
# File lib/active_hash/relation.rb, line 34 def find_by(options) where(options).first end
find_by!(options)
click to toggle source
# File lib/active_hash/relation.rb, line 38 def find_by!(options) find_by(options) || (raise RecordNotFound.new("Couldn't find #{klass.name}")) end
find_by_id(id)
click to toggle source
# File lib/active_hash/relation.rb, line 60 def find_by_id(id) index = klass.send(:record_index)[id.to_s] # TODO: Make index in Base publicly readable instead of using send? index and records[index] end
order(*options)
click to toggle source
# File lib/active_hash/relation.rb, line 77 def order(*options) check_if_method_has_arguments!(:order, options) relation = where({}) return relation if options.blank? processed_args = preprocess_order_args(options) candidates = relation.dup order_by_args!(candidates, processed_args) candidates end
pluck(*column_names)
click to toggle source
# File lib/active_hash/relation.rb, line 69 def pluck(*column_names) column_names.map { |column_name| all.map(&column_name.to_sym) }.inject(&:zip) end
reload()
click to toggle source
# File lib/active_hash/relation.rb, line 73 def reload @records = filter_all_records_by_query_hash end
to_ary()
click to toggle source
# File lib/active_hash/relation.rb, line 90 def to_ary records.dup end
where(query_hash = :chain)
click to toggle source
# File lib/active_hash/relation.rb, line 18 def where(query_hash = :chain) return ActiveHash::Base::WhereChain.new(self) if query_hash == :chain self.records_dirty = true unless query_hash.nil? || query_hash.keys.empty? self.query_hash.merge!(query_hash || {}) self end
Private Instance Methods
check_if_method_has_arguments!(method_name, args)
click to toggle source
# File lib/active_hash/relation.rb, line 148 def check_if_method_has_arguments!(method_name, args) return unless args.blank? raise ArgumentError, "The method .#{method_name}() must contain arguments." end
filter_all_records_by_query_hash()
click to toggle source
# File lib/active_hash/relation.rb, line 109 def filter_all_records_by_query_hash self.records_dirty = false return all_records if query_hash.blank? # use index if searching by id if query_hash.key?(:id) || query_hash.key?("id") ids = (query_hash.delete(:id) || query_hash.delete("id")) ids = range_to_array(ids) if ids.is_a?(Range) candidates = Array.wrap(ids).map { |id| klass.find_by_id(id) }.compact end return candidates if query_hash.blank? (candidates || all_records || []).select do |record| match_options?(record, query_hash) end end
match_options?(record, options)
click to toggle source
# File lib/active_hash/relation.rb, line 127 def match_options?(record, options) options.all? do |col, match| if match.kind_of?(Array) match.any? { |v| normalize(v) == normalize(record[col]) } else normalize(record[col]) == normalize(match) end end end
normalize(v)
click to toggle source
# File lib/active_hash/relation.rb, line 137 def normalize(v) v.respond_to?(:to_sym) ? v.to_sym : v end
order_by_args!(candidates, args)
click to toggle source
# File lib/active_hash/relation.rb, line 163 def order_by_args!(candidates, args) args.each do |arg| field, dir = if arg.is_a?(Hash) arg.to_a.flatten.map(&:to_sym) elsif arg.is_a?(Array) arg.map(&:to_sym) else arg.to_sym end candidates.sort! do |a, b| if dir.present? && dir.to_sym.upcase.equal?(:DESC) b[field] <=> a[field] else a[field] <=> b[field] end end end end
preprocess_order_args(order_args)
click to toggle source
# File lib/active_hash/relation.rb, line 155 def preprocess_order_args(order_args) order_args.reject!(&:blank?) return order_args.reverse! unless order_args.first.is_a?(String) ary = order_args.first.split(', ') ary.map! { |e| e.split(/\W+/) }.reverse! end
range_to_array(range)
click to toggle source
# File lib/active_hash/relation.rb, line 141 def range_to_array(range) return range.to_a unless range.end.nil? e = records.last[:id] (range.begin..e).to_a end
records()
click to toggle source
# File lib/active_hash/relation.rb, line 101 def records if @records.nil? || records_dirty reload else @records end end