Class: ClosureTree::Support

Inherits:
Object
  • Object
show all
Includes:
SupportAttributes, SupportFlags
Defined in:
lib/closure_tree/support.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SupportAttributes

#attribute_names, #base_class, #connection, #hierarchy_class_name, #name_column, #name_sym, #order_column, #order_column_sym, #parent_column_name, #parent_column_sym, #quoted_hierarchy_table_name, #quoted_id_column_name, #quoted_name_column, #quoted_order_column, #quoted_parent_column_name, #quoted_table_name, #require_order_column, #short_hierarchy_class_name, #table_name

Methods included from SupportFlags

#has_name?, #has_type?, #include_forbidden_attributes_protection?, #order_is_numeric?, #order_option?, #subclass?, #use_attr_accessible?

Constructor Details

#initialize(model_class, options) ⇒ Support

Returns a new instance of Support.

Raises:

  • (IllegalArgumentException)


12
13
14
15
16
17
18
19
20
21
22
# File 'lib/closure_tree/support.rb', line 12

def initialize(model_class, options)
  @model_class = model_class
  @options = {
    :base_class => model_class,
    :parent_column_name => 'parent_id',
    :dependent => :nullify, # or :destroy or :delete_all -- see the README
    :name_column => 'name',
    :with_advisory_lock => true
  }.merge(options)
  raise IllegalArgumentException, "name_column can't be 'path'" if options[:name_column] == 'path'
end

Instance Attribute Details

#model_classObject (readonly)

Returns the value of attribute model_class.



9
10
11
# File 'lib/closure_tree/support.rb', line 9

def model_class
  @model_class
end

#optionsObject (readonly)

Returns the value of attribute options.



10
11
12
# File 'lib/closure_tree/support.rb', line 10

def options
  @options
end

Instance Method Details

#has_many_with_order_option(opts) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/closure_tree/support.rb', line 79

def has_many_with_order_option(opts)
  if ActiveRecord::VERSION::MAJOR > 3
    order_options = [opts[:order], options[:order]].compact
    [lambda { order(order_options) }, opts.except(:order)]
  else
    [with_order_option(opts)]
  end
end

#has_many_without_order_option(opts) ⇒ Object

lambda-ize the order, but don’t apply the default order_option



71
72
73
74
75
76
77
# File 'lib/closure_tree/support.rb', line 71

def has_many_without_order_option(opts)
  if ActiveRecord::VERSION::MAJOR > 3
    [lambda { order(opts[:order]) }, opts.except(:order)]
  else
    [opts]
  end
end

#hierarchy_class_for_modelObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/closure_tree/support.rb', line 24

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
    include ActiveModel::ForbiddenAttributesProtection if include_forbidden_attributes_protection
    belongs_to :ancestor, :class_name => "#{model_class}"
    belongs_to :descendant, :class_name => "#{model_class}"
    attr_accessible :ancestor, :descendant, :generations if use_attr_accessible
    def ==(other)
      self.class == other.class && ancestor_id == other.ancestor_id && descendant_id == other.descendant_id
    end
    alias :eql? :==
    def hash
      ancestor_id.hash << 31 ^ descendant_id.hash
    end
  RUBY
  hierarchy_class.table_name = hierarchy_table_name
  hierarchy_class
end

#hierarchy_table_nameObject



45
46
47
48
49
50
51
52
53
# File 'lib/closure_tree/support.rb', line 45

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

#ids_from(scope) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/closure_tree/support.rb', line 94

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

#quote(field) ⇒ Object



55
56
57
# File 'lib/closure_tree/support.rb', line 55

def quote(field)
  connection.quote(field)
end

#remove_prefix_and_suffix(table_name) ⇒ Object



88
89
90
91
92
# File 'lib/closure_tree/support.rb', line 88

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

#scope_with_order(scope, additional_order_by = nil) ⇒ Object



66
67
68
# File 'lib/closure_tree/support.rb', line 66

def scope_with_order(scope, additional_order_by = nil)
  order_option? ? scope.order(*([additional_order_by, options[:order]].compact)) : scope
end

#with_advisory_lock(&block) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/closure_tree/support.rb', line 102

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

#with_order_option(opts) ⇒ Object



59
60
61
62
63
64
# File 'lib/closure_tree/support.rb', line 59

def with_order_option(opts)
  if order_option?
    opts[:order] = [opts[:order], options[:order]].compact.join(",")
  end
  opts
end