Module: ActsAsDAG::ActMethod

Defined in:
lib/acts_as_dag/acts_as_dag.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.descendant_table_entriesObject

Returns a relation scoping to only descendant table entries table entries that match the link conditions



51
52
53
# File 'lib/acts_as_dag/acts_as_dag.rb', line 51

def self.descendant_table_entries
  descendant_class.where(acts_as_dag_options[:link_conditions])
end

Returns a relation scoping to only link table entries that match the link conditions



46
47
48
# File 'lib/acts_as_dag/acts_as_dag.rb', line 46

def self.link_table_entries
  link_class.where(acts_as_dag_options[:link_conditions])
end

Instance Method Details

#acts_as_dag(options = {}) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
93
94
95
96
97
98
99
100
101
# File 'lib/acts_as_dag/acts_as_dag.rb', line 4

def acts_as_dag(options = {})
  class_attribute :acts_as_dag_options
  options.assert_valid_keys :link_class, :descendant_class, :link_table, :descendant_table, :link_conditions
  options.reverse_merge!(
    :link_class => "#{self.name}Link",
    :link_table => "acts_as_dag_links",
    :descendant_class => "#{self.name}Descendant",
    :descendant_table => "acts_as_dag_descendants",
    :link_conditions => {:category_type => self.name})
  self.acts_as_dag_options = options

  # Create Link and Descendant Classes
  class_eval "    class ::\#{options[:link_class]} < ActsAsDAG::AbstractLink\n      self.table_name = '\#{options[:link_table]}'\n      belongs_to :parent,     :class_name => '\#{self.name}', :foreign_key => :parent_id, :inverse_of => :child_links\n      belongs_to :child,      :class_name => '\#{self.name}', :foreign_key => :child_id, :inverse_of => :parent_links\n\n      after_save Proc.new {|link| HelperMethods.update_transitive_closure_for_new_link(link) }\n      after_destroy Proc.new {|link| HelperMethods.update_transitive_closure_for_destroyed_link(link) }\n\n      def node_class; \#{self.name} end\n    end\n\n    class ::\#{options[:descendant_class]} < ActsAsDAG::AbstractDescendant\n      self.table_name = '\#{options[:descendant_table]}'\n      belongs_to :ancestor,   :class_name => '\#{self.name}', :foreign_key => :ancestor_id\n      belongs_to :descendant, :class_name => '\#{self.name}', :foreign_key => :descendant_id\n\n      def node_class; \#{self.name} end\n    end\n\n    def self.link_class\n      ::\#{options[:link_class]}\n    end\n\n    def self.descendant_class\n      ::\#{options[:descendant_class]}\n    end\n  EOV\n\n  # Returns a relation scoping to only link table entries that match the link conditions\n  def self.link_table_entries\n    link_class.where(acts_as_dag_options[:link_conditions])\n  end\n\n  # Returns a relation scoping to only descendant table entries table entries that match the link conditions\n  def self.descendant_table_entries\n    descendant_class.where(acts_as_dag_options[:link_conditions])\n  end\n\n  # Ancestors and descendants returned *include* self, e.g. A's descendants are [A,B,C,D]\n  # Ancestors must always be returned in order of most distant to least\n  # Descendants must always be returned in order of least distant to most\n  # NOTE: Rails 4.0.0 currently ignores the order clause when eager loading, so results may not be returned in the correct order\n  # NOTE: multiple instances of the same descendant/ancestor may be returned if there are multiple paths from ancestor to descendant\n  #   A\n  #  / \\\n  # B   C\n  #  \\ /\n  #   D\n  #\n  has_many :ancestors,        :through => :ancestor_links, :source => :ancestor\n  has_many :descendants,      :through => :descendant_links, :source => :descendant\n\n  has_many :path,             :through => :path_links, :source => :ancestor\n  has_many :subtree,          :through => :subtree_links, :source => :descendant\n\n  has_many :ancestor_links,   lambda { where(options[:link_conditions]).where(\"ancestor_id != descendant_id\").order(\"distance DESC\") }, :class_name => descendant_class, :foreign_key => 'descendant_id'\n  has_many :descendant_links, lambda { where(options[:link_conditions]).where(\"descendant_id != ancestor_id\").order(\"distance ASC\") }, :class_name => descendant_class, :foreign_key => 'ancestor_id'\n\n  has_many :path_links,       lambda { where(options[:link_conditions]).order(\"distance DESC\") }, :class_name => descendant_class, :foreign_key => 'descendant_id', :dependent => :delete_all\n  has_many :subtree_links,    lambda { where(options[:link_conditions]).order(\"distance ASC\") }, :class_name => descendant_class, :foreign_key => 'ancestor_id', :dependent => :delete_all\n\n  has_many :parents,          :through => :parent_links, :source => :parent\n  has_many :children,         :through => :child_links, :source => :child\n\n  has_many :parent_links,     lambda { where options[:link_conditions] }, :class_name => link_class, :foreign_key => 'child_id', :dependent => :delete_all, :inverse_of => :child\n  has_many :child_links,      lambda { where options[:link_conditions] }, :class_name => link_class, :foreign_key => 'parent_id', :dependent => :delete_all, :inverse_of => :parent\n\n  # NOTE: Use select to prevent ActiveRecord::ReadOnlyRecord if the returned records are modified\n  scope :roots,               lambda { joins(:parent_links).where(link_class.table_name => {:parent_id => nil}) }\n  scope :leaves,               lambda { joins(\"LEFT OUTER JOIN \#{link_class.table_name} ON \#{table_name}.id = parent_id\").where(link_class.table_name => {:child_id => nil}).uniq }\n  scope :children,            lambda { joins(:parent_links).where.not(link_class.table_name => {:parent_id => nil}).uniq }\n  scope :parent_records,      lambda { joins(:child_links).where.not(link_class.table_name => {:child_id => nil}).uniq }\n\n  scope :ancestors_of,        lambda {|record| joins(:descendant_links).where(\"descendant_id = ?\", record) }\n  scope :descendants_of,      lambda {|record| joins(:ancestor_links).where(\"ancestor_id = ?\", record) }\n  scope :path_of,             lambda {|record| joins(:subtree_links).where(\"descendant_id = ?\", record) }\n  scope :subtree_of,          lambda {|record| joins(:path_links).where(\"ancestor_id = ?\", record) }\n\n  after_create :initialize_dag\n\n  extend ActsAsDAG::ClassMethods\n  include ActsAsDAG::InstanceMethods\n  extend ActsAsDAG::Deprecated::ClassMethods\n  include ActsAsDAG::Deprecated::InstanceMethods\nend\n"