Module: Familyable::Relationships::ClassMethods

Defined in:
lib/familyable/concerns/relationships.rb,
lib/familyable/concerns/relationships.rb

Overview

*****************************

Utilities

*****************************

Instance Method Summary collapse

Instance Method Details

#children_of(id_sql) ⇒ Object

ID LISTS



71
72
73
74
75
76
77
78
79
80
# File 'lib/familyable/concerns/relationships.rb', line 71

def children_of(id_sql)
  id_sql = safe_identifier(id_sql)
  tree_sql =  <<-SQL
    SELECT DISTINCT #{relationship_table_name}.child_id 
    FROM #{table_name}
    JOIN #{relationship_table_name} 
    ON #{table_name}.id = #{relationship_table_name}.#{parent_field_name}
    WHERE #{table_name}.id = #{id_sql}
  SQL
end

#descendents_of(id_sql) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/familyable/concerns/relationships.rb', line 82

def descendents_of(id_sql)
  id_sql = safe_identifier(id_sql)
  tree_sql =  <<-SQL
    WITH RECURSIVE search_tree(id, path) AS (
        SELECT id, ARRAY[id]
        FROM #{table_name}
        WHERE id = #{id_sql}
      UNION ALL
        SELECT #{table_name}.id, path || #{table_name}.id
        FROM search_tree
        JOIN #{relationship_table_name} ON #{relationship_table_name}.#{parent_field_name} = search_tree.id
        JOIN #{table_name} ON #{table_name}.id = #{relationship_table_name}.child_id
        WHERE NOT #{table_name}.id = ANY(path)
    )
    SELECT id FROM search_tree ORDER BY path
  SQL
end

#elders_of(id_sql) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/familyable/concerns/relationships.rb', line 100

def elders_of(id_sql)
  id_sql = safe_identifier(id_sql)
  tree_sql =  <<-SQL
    WITH RECURSIVE search_tree(id, path) AS (
        SELECT id, ARRAY[id]
        FROM #{table_name}
        WHERE id = #{id_sql}
      UNION ALL
        SELECT #{table_name}.id, path || #{table_name}.id
        FROM search_tree
        JOIN #{relationship_table_name} ON #{relationship_table_name}.child_id = search_tree.id
        JOIN #{table_name} ON #{table_name}.id = #{relationship_table_name}.#{parent_field_name}
        WHERE NOT #{table_name}.id = ANY(path)
    )
    SELECT id FROM search_tree ORDER BY path
  SQL
end

#inv_relationships_nameObject



157
158
159
160
161
162
# File 'lib/familyable/concerns/relationships.rb', line 157

def inv_relationships_name
 if @inv_relationships_name.nil?
     @inv_relationships_name = "inverse_#{relationships_name}"
  end
  @inv_relationships_name
end

#mastersObject



21
22
23
# File 'lib/familyable/concerns/relationships.rb', line 21

def masters
  where(without_parents_where_sql)
end

#model_nameObject



143
144
145
146
147
148
# File 'lib/familyable/concerns/relationships.rb', line 143

def model_name
 if @model_name.nil?
     @model_name = "#{self.name.split("::").last.downcase}"
  end
  @model_name
end

#parent_field_nameObject



164
165
166
167
168
169
# File 'lib/familyable/concerns/relationships.rb', line 164

def parent_field_name
  if @parent_field_name.nil?
     @parent_field_name = "#{self.name.split("::").last.downcase}_id"
  end
  @parent_field_name
end

#relationship_class_nameObject



136
137
138
139
140
141
# File 'lib/familyable/concerns/relationships.rb', line 136

def relationship_class_name
 if @relationship_class_name.nil?
     @relationship_class_name = "#{self.name.split("::").last}Relationship"
  end
  @relationship_class_name
end

#relationship_table_nameObject

UTILS



129
130
131
132
133
134
# File 'lib/familyable/concerns/relationships.rb', line 129

def relationship_table_name
  if @relationship_table_name.nil?
     @relationship_table_name = "#{table_name.singularize}_relationships"
  end
  @relationship_table_name
end

#relationships_nameObject



150
151
152
153
154
155
# File 'lib/familyable/concerns/relationships.rb', line 150

def relationships_name
 if @relationships_name.nil?
     @relationships_name = "#{self.name.split("::").last.downcase}_relationships"
  end
  @relationships_name
end

#safe_identifier(id_sql) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/familyable/concerns/relationships.rb', line 171

def safe_identifier id_sql
  if id_sql.to_i == 0
    "(#{id_sql})"
  else
    id_sql
  end
end

#without_parents_where_sqlObject



118
119
120
121
122
123
# File 'lib/familyable/concerns/relationships.rb', line 118

def without_parents_where_sql
  "#{table_name}.id NOT IN (
    SELECT DISTINCT #{relationship_table_name}.child_id
    FROM #{relationship_table_name}
  )"
end