class OccamsRecord::Results::Row
Abstract class for result rows.
Like ActiveRecord, Boolean columns have field? methods. However, unlike ActiveRecord, other column types do NOT.
Constants
- IDS_SUFFIX
Attributes
Array of associations names
Array of column names
Name of Rails model
Name of primary key column (nil if column wasn't in the SELECT)
Name of originating database table
Public Class Methods
Initialize a new result row.
@param raw_values [Array] array of raw values from db
# File lib/occams-record/results/row.rb, line 31 def initialize(raw_values) @raw_values = raw_values @cast_values = {} end
Public Instance Methods
Returns true if the two objects are from the same table and have the same primary key.
@param obj [OccamsRecord::Results::Row] @return [Boolean]
# File lib/occams-record/results/row.rb, line 52 def ==(obj) super || obj.is_a?(OccamsRecord::Results::Row) && obj.class.table_name && obj.class.table_name == self.class.table_name && (pkey1 = obj.class.primary_key) && (pkey2 = self.class.primary_key) && obj.send(pkey1) == self.send(pkey2) end
Hash-like accessor for attributes and associations.
@param attr [String|Symbol\ @return [Object]
# File lib/occams-record/results/row.rb, line 42 def [](attr) respond_to?(attr) ? send(attr) : nil end
Returns a string with the “real” model name and raw result values.
Weird note - if this string is longer than 65 chars it won't be used in exception messages. bugs.ruby-lang.org/issues/8982
@return [String]
# File lib/occams-record/results/row.rb, line 105 def inspect id = self.class.primary_key ? send(self.class.primary_key) : "none" "#<#{self.class.model_name || "Anonymous"} #{self.class.primary_key}: #{id}>" end
# File lib/occams-record/results/row.rb, line 111 def method_missing(name, *args, &block) model = self.class._model return super if args.any? or !block.nil? or model.nil? name_str = name.to_s assoc = name_str.sub(IDS_SUFFIX, "").pluralize if name_str =~ IDS_SUFFIX and can_define_ids_reader? assoc define_ids_reader! assoc send name elsif model.reflections.has_key? name_str raise MissingEagerLoadError.new(self, name) elsif model.columns_hash.has_key? name_str raise MissingColumnError.new(self, name) else super end end
# File lib/occams-record/results/row.rb, line 129 def respond_to_missing?(name, _include_private = false) model = self.class._model return super if model.nil? name_str = name.to_s assoc = name_str.sub(IDS_SUFFIX, "").pluralize if name_str =~ IDS_SUFFIX and can_define_ids_reader? assoc true else super end end
Return row as a Hash. By default the hash does NOT include associations.
@param symbolize_names [Boolean] if true, make Hash keys Symbols instead of Strings @param recursive [Boolean] if true, include assiciations and them (and their associations) to hashes. @return [Hash] a Hash with String or Symbol keys
# File lib/occams-record/results/row.rb, line 67 def to_h(symbolize_names: false, recursive: false) hash = self.class.columns.reduce({}) { |a, col_name| key = symbolize_names ? col_name.to_sym : col_name a[key] = send col_name a } recursive ? self.class.associations.reduce(hash) { |a, assoc_name| key = symbolize_names ? assoc_name.to_sym : assoc_name assoc = send assoc_name a[key] = if assoc.is_a? Array assoc.map { |x| x.to_h(symbolize_names: symbolize_names, recursive: true) } elsif assoc assoc.to_h(symbolize_names: symbolize_names, recursive: true) end a } : hash end
Returns the name of the model and the attributes.
@return [String]
# File lib/occams-record/results/row.rb, line 93 def to_s "#{self.class.model_name || "Anonymous"}#{to_h(symbolize_names: true, recursive: false)}" end
Private Instance Methods
# File lib/occams-record/results/row.rb, line 144 def can_define_ids_reader?(assoc) model = self.class._model self.class.associations.include?(assoc) && (ref = model.reflections[assoc]) && !ref.polymorphic? && (ref.macro == :has_many || ref.macro == :has_and_belongs_to_many) end
# File lib/occams-record/results/row.rb, line 152 def define_ids_reader!(assoc) model = self.class._model ref = model.reflections[assoc] pkey = ref.klass.primary_key.to_sym self.class.class_eval do define_method "#{assoc.singularize}_ids" do begin self.send(assoc).map(&pkey).uniq rescue NoMethodError => e raise MissingColumnError.new(self, e.name) end end end end