Class: DataGraph::Linkage

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/data_graph/linkage.rb

Direct Known Subclasses

CpkLinkage

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

cpk?, foreign_key, patherize_attrs, primary_keys, reference_key

Constructor Details

#initialize(assoc, options = {}) ⇒ Linkage

Returns a new instance of Linkage.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/data_graph/linkage.rb', line 16

def initialize(assoc, options={})
  @macro = assoc.macro
  @name = assoc.name
  @through = nil
  
  case macro
  when :belongs_to
    @parent_columns = foreign_key(assoc)
    @child_columns  = reference_key(assoc)
  when :has_many, :has_one
    if through_assoc = assoc.through_reflection
      @through = assoc.source_reflection.name
      
      assoc = through_assoc
      options = {:only => [], :include => {@through => options}}
    end
    
    @parent_columns = reference_key(assoc)
    @child_columns  = foreign_key(assoc)
  else
    raise "currently unsupported association macro: #{macro}"
  end
  
  klass = assoc.klass
  @child_node = Node.new(assoc.klass, options)
  @table_name = klass.table_name
  @connection = klass.connection
end

Instance Attribute Details

#child_columnsObject (readonly)

Returns the value of attribute child_columns.



13
14
15
# File 'lib/data_graph/linkage.rb', line 13

def child_columns
  @child_columns
end

#child_nodeObject (readonly)

Returns the value of attribute child_node.



14
15
16
# File 'lib/data_graph/linkage.rb', line 14

def child_node
  @child_node
end

#connectionObject (readonly)

Returns the value of attribute connection.



11
12
13
# File 'lib/data_graph/linkage.rb', line 11

def connection
  @connection
end

#macroObject (readonly)

Returns the value of attribute macro.



7
8
9
# File 'lib/data_graph/linkage.rb', line 7

def macro
  @macro
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/data_graph/linkage.rb', line 8

def name
  @name
end

#parent_columnsObject (readonly)

Returns the value of attribute parent_columns.



12
13
14
# File 'lib/data_graph/linkage.rb', line 12

def parent_columns
  @parent_columns
end

#table_nameObject (readonly)

Returns the value of attribute table_name.



10
11
12
# File 'lib/data_graph/linkage.rb', line 10

def table_name
  @table_name
end

#throughObject (readonly)

Returns the value of attribute through.



9
10
11
# File 'lib/data_graph/linkage.rb', line 9

def through
  @through
end

Instance Method Details

#child_id(record) ⇒ Object



53
54
55
# File 'lib/data_graph/linkage.rb', line 53

def child_id(record)
  record.send child_columns.at(0)
end

#conditions(id_map) ⇒ Object



57
58
59
# File 'lib/data_graph/linkage.rb', line 57

def conditions(id_map)
  ["#{table_name}.#{connection.quote_column_name(child_columns.at(0))} IN (?)", id_map.keys.flatten]
end

#inherit(method_name, paths) ⇒ Object



94
95
96
# File 'lib/data_graph/linkage.rb', line 94

def inherit(method_name, paths)
  dup.inherit!(method_name, paths)
end

#inherit!(method_name, paths) ⇒ Object



98
99
100
101
102
# File 'lib/data_graph/linkage.rb', line 98

def inherit!(method_name, paths)
  paths = paths.collect {|path| "#{through}.#{path}"} if through
  @child_node = @child_node.send(method_name, paths)
  self
end


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/data_graph/linkage.rb', line 61

def link(parents)
  id_map = Hash.new {|hash, key| hash[key] = [] }
  
  parents = arrayify(parents)
  parents.each do |parent|
    id_map[parent_id(parent)] << parent
  end
  
  children = child_node.find(:all, 
    :select => child_columns, 
    :conditions => conditions(id_map))
  visited = []
  
  arrayify(children).each do |child|
    id_map[child_id(child)].each do |parent|
      visited << parent
      set_child(parent, child)
    end
  end
  
  if macro == :has_many && through
    visited.each do |parent|
      parent.send(name).uniq!
    end
  end
  
  (parents - visited).each do |parent|
    set_child(parent, nil)
  end
  
  children
end

#nodeObject



45
46
47
# File 'lib/data_graph/linkage.rb', line 45

def node
  through ? child_node[through] : child_node
end

#parent_id(record) ⇒ Object



49
50
51
# File 'lib/data_graph/linkage.rb', line 49

def parent_id(record)
  record.send parent_columns.at(0)
end