lib/closure_tree/support.rb in closure_tree-4.1.0 vs lib/closure_tree/support.rb in closure_tree-4.2.0
- old
+ new
@@ -1,7 +1,12 @@
+require 'closure_tree/support_flags'
+require 'closure_tree/support_attributes'
+
module ClosureTree
class Support
+ include ClosureTree::SupportFlags
+ include ClosureTree::SupportAttributes
attr_reader :model_class
attr_reader :options
def initialize(model_class, options)
@@ -14,26 +19,10 @@
:with_advisory_lock => true
}.merge(options)
raise IllegalArgumentException, "name_column can't be 'path'" if options[:name_column] == 'path'
end
- def connection
- model_class.connection
- end
-
- def use_attr_accessible?
- ActiveRecord::VERSION::MAJOR == 3 &&
- defined?(ActiveModel::MassAssignmentSecurity) &&
- model_class.ancestors.include?(ActiveModel::MassAssignmentSecurity)
- end
-
- def include_forbidden_attributes_protection?
- ActiveRecord::VERSION::MAJOR == 3 &&
- defined?(ActiveModel::ForbiddenAttributesProtection) &&
- model_class.ancestors.include?(ActiveModel::ForbiddenAttributesProtection)
- end
-
def hierarchy_class_for_model
hierarchy_class = model_class.parent.const_set(short_hierarchy_class_name, Class.new(ActiveRecord::Base))
use_attr_accessible = use_attr_accessible?
include_forbidden_attributes_protection = include_forbidden_attributes_protection?
hierarchy_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -51,79 +40,24 @@
RUBY
hierarchy_class.table_name = hierarchy_table_name
hierarchy_class
end
- def parent_column_name
- options[:parent_column_name]
- end
-
- def parent_column_sym
- parent_column_name.to_sym
- end
-
- def has_name?
- model_class.new.attributes.include? options[:name_column]
- end
-
- def name_column
- options[:name_column]
- end
-
- def name_sym
- name_column.to_sym
- end
-
def hierarchy_table_name
# We need to use the table_name, not something like ct_class.to_s.demodulize + "_hierarchies",
# because they may have overridden the table name, which is what we want to be consistent with
# in order for the schema to make sense.
tablename = options[:hierarchy_table_name] ||
remove_prefix_and_suffix(table_name).singularize + "_hierarchies"
ActiveRecord::Base.table_name_prefix + tablename + ActiveRecord::Base.table_name_suffix
end
- def hierarchy_class_name
- options[:hierarchy_class_name] || model_class.to_s + "Hierarchy"
- end
-
- # Returns the constant name of the hierarchy_class
- #
- # @return [String] the constant name
- #
- # @example
- # Namespace::Model.hierarchy_class_name # => "Namespace::ModelHierarchy"
- # Namespace::Model.short_hierarchy_class_name # => "ModelHierarchy"
- def short_hierarchy_class_name
- hierarchy_class_name.split('::').last
- end
-
- def quoted_hierarchy_table_name
- connection.quote_table_name hierarchy_table_name
- end
-
- def quoted_id_column_name
- connection.quote_column_name model_class.primary_key
- end
-
- def quoted_parent_column_name
- connection.quote_column_name parent_column_name
- end
-
- def quoted_name_column
- connection.quote_column_name name_column
- end
-
def quote(field)
connection.quote(field)
end
- def order_option?
- !options[:order].nil?
- end
-
def with_order_option(opts)
if order_option?
opts[:order] = [opts[:order], options[:order]].compact.join(",")
end
opts
@@ -149,68 +83,10 @@
else
[with_order_option(opts)]
end
end
- def order_is_numeric?
- # The table might not exist yet (in the case of ActiveRecord::Observer use, see issue 32)
- return false if !order_option? || !model_class.table_exists?
- c = model_class.columns_hash[order_column]
- c && c.type == :integer
- end
-
- def order_column
- o = options[:order]
- if o.nil?
- nil
- elsif o.is_a?(String)
- o.split(' ', 2).first
- else
- o.to_s
- end
- end
-
- def require_order_column
- raise ":order value, '#{options[:order]}', isn't a column" if order_column.nil?
- end
-
- def order_column_sym
- require_order_column
- order_column.to_sym
- end
-
- def quoted_order_column(include_table_name = true)
- require_order_column
- prefix = include_table_name ? "#{quoted_table_name}." : ""
- "#{prefix}#{connection.quote_column_name(order_column)}"
- end
-
- # This is the "topmost" class. This will only potentially not be ct_class if you are using STI.
- def base_class
- options[:base_class]
- end
-
- def subclass?
- model_class != model_class.base_class
- end
-
- def attribute_names
- @attribute_names ||= model_class.new.attributes.keys - model_class.protected_attributes.to_a
- end
-
- def has_type?
- attribute_names.include? 'type'
- end
-
- def table_name
- model_class.table_name
- end
-
- def quoted_table_name
- connection.quote_table_name table_name
- end
-
def remove_prefix_and_suffix(table_name)
prefix = Regexp.escape(ActiveRecord::Base.table_name_prefix)
suffix = Regexp.escape(ActiveRecord::Base.table_name_suffix)
table_name.gsub(/^#{prefix}(.+)#{suffix}$/, "\\1")
end
@@ -218,9 +94,21 @@
def ids_from(scope)
if scope.respond_to? :pluck
scope.pluck(model_class.primary_key)
else
scope.select(model_class.primary_key).map { |ea| ea._ct_id }
+ end
+ end
+
+ def with_advisory_lock(&block)
+ if options[:with_advisory_lock]
+ model_class.with_advisory_lock("closure_tree") do
+ model_class.transaction do
+ yield
+ end
+ end
+ else
+ yield
end
end
end
end