Module: CollectiveIdea::Acts::NestedSet::ClassMethods

Defined in:
lib/awesome_nested_set.rb

Instance Method Summary collapse

Instance Method Details

#all_roots_valid?Boolean

Wrapper for each_root_valid? that can deal with scope.

Returns:

  • (Boolean)


142
143
144
145
146
147
148
149
150
# File 'lib/awesome_nested_set.rb', line 142

def all_roots_valid?
  if acts_as_nested_set_options[:scope]
    roots(:group => scope_column_names).group_by{|record| scope_column_names.collect{|col| record.send(col.to_sym)}}.all? do |scope, grouped_roots|
      each_root_valid?(grouped_roots)
    end
  else
    each_root_valid?(roots)
  end
end

#each_root_valid?(roots_to_validate) ⇒ Boolean

Returns:

  • (Boolean)


152
153
154
155
156
157
158
159
160
# File 'lib/awesome_nested_set.rb', line 152

def each_root_valid?(roots_to_validate)
  left = right = 0
  roots_to_validate.all? do |root|
    returning(root.left > left && root.right > right) do
      left = root.left
      right = root.right
    end
  end
end

#left_and_rights_valid?Boolean

Returns:

  • (Boolean)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/awesome_nested_set.rb', line 113

def left_and_rights_valid?
  count(
    :joins => "LEFT OUTER JOIN #{quoted_table_name} AS parent ON " +
      "#{quoted_table_name}.#{quoted_parent_column_name} = parent.#{primary_key}",
    :conditions =>
      "#{quoted_table_name}.#{quoted_left_column_name} IS NULL OR " +
      "#{quoted_table_name}.#{quoted_right_column_name} IS NULL OR " +
      "#{quoted_table_name}.#{quoted_left_column_name} >= " +
        "#{quoted_table_name}.#{quoted_right_column_name} OR " +
      "(#{quoted_table_name}.#{quoted_parent_column_name} IS NOT NULL AND " +
        "(#{quoted_table_name}.#{quoted_left_column_name} <= parent.#{quoted_left_column_name} OR " +
        "#{quoted_table_name}.#{quoted_right_column_name} >= parent.#{quoted_right_column_name}))"
  ) == 0
end

#no_duplicates_for_columns?Boolean

Returns:

  • (Boolean)


128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/awesome_nested_set.rb', line 128

def no_duplicates_for_columns?
  scope_string = Array(acts_as_nested_set_options[:scope]).map do |c|
    connection.quote_column_name(c)
  end.push(nil).join(", ")
  [quoted_left_column_name, quoted_right_column_name].all? do |column|
    # No duplicates
    find(:first, 
      :select => "#{scope_string}#{column}, COUNT(#{column})", 
      :group => "#{scope_string}#{column} 
        HAVING COUNT(#{column}) > 1").nil?
  end
end

#rebuild!Object

Rebuilds the left & rights if unset or invalid. Also very useful for converting from acts_as_tree.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/awesome_nested_set.rb', line 163

def rebuild!
  # Don't rebuild a valid tree.
  return true if valid?
  
  scope = lambda{}
  if acts_as_nested_set_options[:scope]
    scope = lambda{|node| 
      scope_column_names.inject(""){|str, column_name|
        str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} "
      }
    }
  end
  indices = {}
  
  set_left_and_rights = lambda do |node|
    # set left
    node[left_column_name] = indices[scope.call(node)] += 1
    # find
    find(:all, :conditions => ["#{quoted_parent_column_name} = ? #{scope.call(node)}", node], :order => "#{quoted_left_column_name}, #{quoted_right_column_name}, id").each{|n| set_left_and_rights.call(n) }
    # set right
    node[right_column_name] = indices[scope.call(node)] += 1    
    node.save!    
  end
                      
  # Find root node(s)
  root_nodes = find(:all, :conditions => "#{quoted_parent_column_name} IS NULL", :order => "#{quoted_left_column_name}, #{quoted_right_column_name}, id").each do |root_node|
    # setup index for this scope
    indices[scope.call(root_node)] ||= 0
    set_left_and_rights.call(root_node)
  end
end

#rootObject

Returns the first root



105
106
107
# File 'lib/awesome_nested_set.rb', line 105

def root
  roots.find(:first)
end

#valid?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/awesome_nested_set.rb', line 109

def valid?
  left_and_rights_valid? && no_duplicates_for_columns? && all_roots_valid?
end