class FlattenRecord::Meta::NormalizedAttr

Public Instance Methods

[](key) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 18
def [](key)
  instance_variable_get("@#{key}") 
end
all_columns() click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 9
def all_columns
  child_columns = @include.values.collect(&:all_columns)
  @base_columns + @methods + @compute + child_columns.flatten 
end
associated_models() click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 14
def associated_models
  @include.blank? ? target_model : @include.values.collect(&:associated_models).flatten
end
denormalize(instance, to_record) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 5
def denormalize(instance, to_record)
  denormalize_children(instance, to_record)
end
id_column() click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 45
def id_column
  return @id_column unless @id_column.nil?
end
prefix() click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 22
def prefix
  custom_prefix || "#{parent.prefix}#{target_model_name}_"
end
traverse_by(attr, value) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 26
def traverse_by(attr, value)
  attr_value = send("#{attr}")

  if !value.respond_to?(:to_s) || !attr_value.respond_to?(:to_s)
    raise "traverse error: to_s method required for comparison"
  end
  
  if value.to_s.downcase == attr_value.to_s.downcase
    return self
  else
    found = nil
    @include.values.each do |node|
      n = node.traverse_by(attr, value)
      found = n unless n.nil?
    end 
    return found
  end
end

Protected Instance Methods

build(definition) click to toggle source
Calls superclass method FlattenRecord::Meta::Node#build
# File lib/flatten_record/meta/normalized_attr.rb, line 57
def build(definition)
  super(definition)
  
  @foreign_keys = []
  primary_key = target_columns.select(&:primary).first
  @id_column = IdColumn.new(self, primary_key, target_model, model)
  
  @compute = build_compute(definition) || []
  @methods = build_methods(definition) || []
  @include = build_children(definition) || {}
  @base_columns = build_columns(definition) || []
  
  validate_columns(all_columns)

  self
end
build_children(definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 122
def build_children(definition)
  return {} unless definition[:include]
  
  children = {}
  definition[:include].each do |child, child_definition|
    class_name = child_definition[:definition][:class_name]
    children[child] = associated_node_factory(self, child, class_name)
    children[child].build(child_definition)
  end
  children
end
build_columns(definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 85
def build_columns(definition)
  cols = columns_from_definition(definition)
  [id_column] + cols 
end
build_compute(definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 90
def build_compute(definition)
  return [] unless definition[:compute] 
  
  definition[:compute].map do |method, type| 
    options = {}
    if type.is_a?(Hash)
      options = type
      type = options[:type]
    end

    ComputeColumn.
      new(self, method, type, target_model, model, options).
      build(definition)
  end
end
build_methods(definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 106
def build_methods(definition)
  return [] unless definition[:methods] 
  
  definition[:methods].map do |method, type|
    options = {}
    if type.is_a?(Hash)
      options = type
      type = options[:sql_type]
    end

    MethodColumn.
      new(self, method, type, target_model, model).
      build(definition)
  end
end
children() click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 81
def children
  (@base_columns + @compute + @methods + @include.values)
end
denormalize_children(instance, to_record) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 50
def denormalize_children(instance, to_record)
  children.each do |child|
    to_record = child.denormalize(instance, to_record)
  end
  to_record
end
validate_columns(columns) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 74
def validate_columns(columns)
  dups = find_dup_columns(columns)
  if dups.present?
    raise "Duplicate columns found: #{dups.join(", ")}"
  end
end

Private Instance Methods

allow_column?(col, definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 195
def allow_column?(col, definition)
  return false if col.primary
  return false if @foreign_keys.include?(col.name.to_s) 

  if definition[:only].present?
    definition[:only].include?(col.name.to_sym) 
  elsif definition[:except].present?
    !definition[:except].include?(col.name.to_sym) 
  else
    true
  end
end
associated_node_factory(parent, child, class_name) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 156
def associated_node_factory(parent, child, class_name)
  association = target_model.reflect_on_association(child)

  raise_missing_macro(child, target_model) unless association.macro
  
  if association_node?(association.macro)
    class_name ||= association.klass
    type = "#{association.macro}"
    klass = Meta.const_get(type.camelize)
    
    @foreign_keys << association.foreign_key.to_s 
    klass.new(parent, association, class_name, model)
  else
    raise_unsupported_type(association.macro, target_model)
  end
end
association_node?(type) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 173
def association_node?(type)
  [:has_many, :belongs_to, :has_one].include?(type) 
end
columns_from_definition(definition) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 185
def columns_from_definition(definition)
  target_columns.
    select {|col| allow_column?(col, definition) }.
    map do |col| 
      Column.
        new(self, col, target_model, model).
        build(definition)
    end
end
find_dup_columns(columns) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 135
def find_dup_columns(columns)
  dups = []
  columns.each do |column|
    if match_columns?(columns, column)
      parent_target = column.parent.target_model
      original_name = column.column.name
      dups << "#{column.name} was from #{parent_target}'s #{original_name}"
    end
  end
  dups
end
match_columns?(columns, column) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 147
def match_columns?(columns, column)
  columns.each do |c|
    if c.parent != column.parent && c.name == column.name
      return true
    end
  end
  false
end
raise_missing_macro(child, model) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 181
def raise_missing_macro(child, model)
  raise "association with '#{child}' on #{model} is not found"
end
raise_unsupported_type(type, model) click to toggle source
# File lib/flatten_record/meta/normalized_attr.rb, line 177
def raise_unsupported_type(type, model)
  raise "association type '#{type}' with '#{model}' is not supported"
end