acts_as_recursive_tree 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +5 -0
- data/lib/acts_as_recursive_tree.rb +1 -0
- data/lib/acts_as_recursive_tree/acts_macro.rb +3 -6
- data/lib/acts_as_recursive_tree/associations.rb +3 -3
- data/lib/acts_as_recursive_tree/builders.rb +1 -0
- data/lib/acts_as_recursive_tree/builders/leaves.rb +1 -1
- data/lib/acts_as_recursive_tree/builders/relation_builder.rb +23 -12
- data/lib/acts_as_recursive_tree/builders/strategy.rb +27 -0
- data/lib/acts_as_recursive_tree/builders/strategy/join.rb +29 -0
- data/lib/acts_as_recursive_tree/builders/strategy/subselect.rb +23 -0
- data/lib/acts_as_recursive_tree/config.rb +22 -0
- data/lib/acts_as_recursive_tree/version.rb +1 -1
- metadata +7 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: a28e3f6eadbc8b37622ef525b25e654b13c0903f4053adb096f4f853f36ccc06
         | 
| 4 | 
            +
              data.tar.gz: f2614872c77bf263526ac596bbb82438b75af1e49e393c6464e07515c5605288
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9a4ccf41395828283e882f8e88b6e9c8a7edea75995219840d2c6d07da69bbb8bb6f15aeec6cddf8a105f4f8ad15d3dfddad2bf7aaeead54074fffa28030bd68
         | 
| 7 | 
            +
              data.tar.gz: c48904528902e0554d1a46dea5883afcc28473597f4df2493ccf1015e80967b2490cae5f41fb5dac9eb7925a2c9d00feeb9637b902366e3dc1be0d6dddc3c7ab
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,8 @@ | |
| 1 | 
            +
            ### Version 2.1.0
         | 
| 2 | 
            +
            - BUGFIX association self_and_siblings not working
         | 
| 3 | 
            +
            - BUGFIX primary_key of model is retrieved on first usage and not on setup
         | 
| 4 | 
            +
            - NEW when no ordering/depth is required, then use subselect instead of joining the temp table
         | 
| 5 | 
            +
             | 
| 1 6 | 
             
            ### Version 2.0.2
         | 
| 2 7 | 
             
            - fix for condition relation was executed before merging
         | 
| 3 8 |  | 
| @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            require 'ostruct'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module ActsAsRecursiveTree
         | 
| 4 2 | 
             
              module ActsMacro
         | 
| 5 3 |  | 
| @@ -11,11 +9,10 @@ module ActsAsRecursiveTree | |
| 11 9 | 
             
                def recursive_tree(parent_key: :parent_id, parent_type_column: nil)
         | 
| 12 10 |  | 
| 13 11 | 
             
                  class_attribute :_recursive_tree_config
         | 
| 14 | 
            -
                  self._recursive_tree_config =  | 
| 15 | 
            -
                     | 
| 12 | 
            +
                  self._recursive_tree_config = Config.new(
         | 
| 13 | 
            +
                    model_class:        self,
         | 
| 16 14 | 
             
                    parent_key:         parent_key.to_sym,
         | 
| 17 | 
            -
                    parent_type_column: parent_type_column.try(:to_sym) | 
| 18 | 
            -
                    depth_column:       :recursive_depth
         | 
| 15 | 
            +
                    parent_type_column: parent_type_column.try(:to_sym)
         | 
| 19 16 | 
             
                  )
         | 
| 20 17 |  | 
| 21 18 | 
             
                  include ActsAsRecursiveTree::Model
         | 
| @@ -17,9 +17,9 @@ module ActsAsRecursiveTree | |
| 17 17 | 
             
                           inverse_of:  :parent
         | 
| 18 18 |  | 
| 19 19 | 
             
                  has_many :self_and_siblings,
         | 
| 20 | 
            -
                            | 
| 21 | 
            -
                            | 
| 22 | 
            -
                            | 
| 20 | 
            +
                           through: :parent,
         | 
| 21 | 
            +
                           source: :children,
         | 
| 22 | 
            +
                           class_name:  self.base_class.to_s
         | 
| 23 23 | 
             
                end
         | 
| 24 24 | 
             
              end
         | 
| 25 25 | 
             
            end
         | 
| @@ -1,5 +1,8 @@ | |
| 1 1 | 
             
            module ActsAsRecursiveTree
         | 
| 2 2 | 
             
              module Builders
         | 
| 3 | 
            +
                #
         | 
| 4 | 
            +
                # Constructs the Arel necessary for recursion.
         | 
| 5 | 
            +
                #
         | 
| 3 6 | 
             
                class RelationBuilder
         | 
| 4 7 |  | 
| 5 8 | 
             
                  def self.build(klass, ids, exclude_ids: false, &block)
         | 
| @@ -9,6 +12,7 @@ module ActsAsRecursiveTree | |
| 9 12 | 
             
                  attr_reader :klass, :ids, :recursive_temp_table, :travers_loc_table, :without_ids
         | 
| 10 13 | 
             
                  mattr_reader(:random) { Random.new }
         | 
| 11 14 |  | 
| 15 | 
            +
                  # Delegators for easier accessing config and query options
         | 
| 12 16 | 
             
                  delegate :primary_key, :depth_column, :parent_key, :parent_type_column, to: :@config
         | 
| 13 17 | 
             
                  delegate :depth_present?, :depth, :condition, :ensure_ordering, to: :@query_opts
         | 
| 14 18 |  | 
| @@ -25,6 +29,13 @@ module ActsAsRecursiveTree | |
| 25 29 | 
             
                    @travers_loc_table    = Arel::Table.new("traverse_#{rand_int}_loc")
         | 
| 26 30 | 
             
                  end
         | 
| 27 31 |  | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  # Constructs a new QueryOptions and yield it to the proc if one is present.
         | 
| 34 | 
            +
                  # Subclasses may override this method to provide sane defaults.
         | 
| 35 | 
            +
                  #
         | 
| 36 | 
            +
                  # @param proc [Proc] a proc or nil
         | 
| 37 | 
            +
                  #
         | 
| 38 | 
            +
                  # @return [ActsAsRecursiveTree::Options::QueryOptions] the new QueryOptions instance
         | 
| 28 39 | 
             
                  def get_query_options(proc)
         | 
| 29 40 | 
             
                    opts = ActsAsRecursiveTree::Options::QueryOptions.new
         | 
| 30 41 |  | 
| @@ -38,18 +49,9 @@ module ActsAsRecursiveTree | |
| 38 49 | 
             
                  end
         | 
| 39 50 |  | 
| 40 51 | 
             
                  def build
         | 
| 41 | 
            -
                     | 
| 42 | 
            -
                      create_select_manger.as(recursive_temp_table.name)
         | 
| 43 | 
            -
                    ).on(
         | 
| 44 | 
            -
                      base_table[primary_key].eq(recursive_temp_table[primary_key])
         | 
| 45 | 
            -
                    )
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                    relation = klass.joins(final_select_mgr.join_sources)
         | 
| 52 | 
            +
                    relation = Strategy.for_query_options(@query_opts).build(self)
         | 
| 48 53 |  | 
| 49 54 | 
             
                    relation = apply_except_id(relation)
         | 
| 50 | 
            -
                    relation = apply_depth(relation)
         | 
| 51 | 
            -
                    relation = apply_order(relation)
         | 
| 52 | 
            -
             | 
| 53 55 | 
             
                    relation
         | 
| 54 56 | 
             
                  end
         | 
| 55 57 |  | 
| @@ -69,8 +71,14 @@ module ActsAsRecursiveTree | |
| 69 71 | 
             
                    relation.order(recursive_temp_table[depth_column].asc)
         | 
| 70 72 | 
             
                  end
         | 
| 71 73 |  | 
| 72 | 
            -
                  def create_select_manger
         | 
| 73 | 
            -
                     | 
| 74 | 
            +
                  def create_select_manger(column = nil)
         | 
| 75 | 
            +
                    projections = if column
         | 
| 76 | 
            +
                      travers_loc_table[column]
         | 
| 77 | 
            +
                    else
         | 
| 78 | 
            +
                      Arel.star
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    travers_loc_table.project(projections).with(:recursive, build_cte_table)
         | 
| 74 82 | 
             
                  end
         | 
| 75 83 |  | 
| 76 84 | 
             
                  def build_cte_table
         | 
| @@ -125,6 +133,9 @@ module ActsAsRecursiveTree | |
| 125 133 | 
             
                    relation.merge(condition)
         | 
| 126 134 | 
             
                  end
         | 
| 127 135 |  | 
| 136 | 
            +
                  #
         | 
| 137 | 
            +
                  # U
         | 
| 138 | 
            +
                  #
         | 
| 128 139 | 
             
                  def build_join_condition
         | 
| 129 140 | 
             
                    raise 'not implemented'
         | 
| 130 141 | 
             
                  end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            module ActsAsRecursiveTree
         | 
| 2 | 
            +
              module Builders
         | 
| 3 | 
            +
                #
         | 
| 4 | 
            +
                # Strategy module for different strategies of how to build the resulting query.
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                module Strategy
         | 
| 7 | 
            +
                  extend ActiveSupport::Autoload
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  autoload :Join
         | 
| 10 | 
            +
                  autoload :Subselect
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  # Returns a Strategy appropriate for query_opts
         | 
| 14 | 
            +
                  #
         | 
| 15 | 
            +
                  # @param query_opts [ActsAsRecursiveTree::Options::QueryOptions]
         | 
| 16 | 
            +
                  #
         | 
| 17 | 
            +
                  # @return a strategy class best suited for the opts
         | 
| 18 | 
            +
                  def self.for_query_options(query_opts)
         | 
| 19 | 
            +
                    if query_opts.depth_present? || query_opts.ensure_ordering
         | 
| 20 | 
            +
                      Join
         | 
| 21 | 
            +
                    else
         | 
| 22 | 
            +
                      Subselect
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            module ActsAsRecursiveTree
         | 
| 2 | 
            +
              module Builders
         | 
| 3 | 
            +
                module Strategy
         | 
| 4 | 
            +
                  #
         | 
| 5 | 
            +
                  # Build a relation using an INNER JOIN.
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  module Join
         | 
| 8 | 
            +
                    #
         | 
| 9 | 
            +
                    # Builds the relation.
         | 
| 10 | 
            +
                    #
         | 
| 11 | 
            +
                    # @param builder [ActsAsRecursiveTree::Builders::RelationBuilder]
         | 
| 12 | 
            +
                    # @return [ActiveRecord::Relation]
         | 
| 13 | 
            +
                    def self.build(builder)
         | 
| 14 | 
            +
                      final_select_mgr = builder.base_table.join(
         | 
| 15 | 
            +
                        builder.create_select_manger.as(builder.recursive_temp_table.name)
         | 
| 16 | 
            +
                      ).on(
         | 
| 17 | 
            +
                        builder.base_table[builder.primary_key].eq(builder.recursive_temp_table[builder.primary_key])
         | 
| 18 | 
            +
                      )
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      relation = builder.klass.joins(final_select_mgr.join_sources)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      relation = builder.apply_depth(relation)
         | 
| 23 | 
            +
                      relation = builder.apply_order(relation)
         | 
| 24 | 
            +
                      relation
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module ActsAsRecursiveTree
         | 
| 2 | 
            +
              module Builders
         | 
| 3 | 
            +
                module Strategy
         | 
| 4 | 
            +
                  #
         | 
| 5 | 
            +
                  # Strategy for building a relation using an WHERE ID IN(...).
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  module Subselect
         | 
| 8 | 
            +
                    #
         | 
| 9 | 
            +
                    # Builds the relation.
         | 
| 10 | 
            +
                    #
         | 
| 11 | 
            +
                    # @param builder [ActsAsRecursiveTree::Builders::RelationBuilder]
         | 
| 12 | 
            +
                    # @return [ActiveRecord::Relation]
         | 
| 13 | 
            +
                    def self.build(builder)
         | 
| 14 | 
            +
                      builder.klass.where(
         | 
| 15 | 
            +
                        builder.base_table[builder.primary_key].in(
         | 
| 16 | 
            +
                          builder.create_select_manger(builder.primary_key)
         | 
| 17 | 
            +
                        )
         | 
| 18 | 
            +
                      )
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module ActsAsRecursiveTree
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # Stores the configuration of one Model class
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              class Config
         | 
| 6 | 
            +
                attr_reader :parent_key, :parent_type_column, :depth_column
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(model_class:, parent_key:, parent_type_column:, depth_column: :recursive_depth)
         | 
| 9 | 
            +
                  @model_class        = model_class
         | 
| 10 | 
            +
                  @parent_key         = parent_key
         | 
| 11 | 
            +
                  @parent_type_column = parent_type_column
         | 
| 12 | 
            +
                  @depth_column       = depth_column
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # Returns the primary key for the model class.
         | 
| 17 | 
            +
                # @return [Symbol]
         | 
| 18 | 
            +
                def primary_key
         | 
| 19 | 
            +
                  @primary_key ||= @model_class.primary_key.to_sym
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: acts_as_recursive_tree
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0 | 
| 4 | 
            +
              version: 2.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Wolfgang Wedelich-John
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-04-06 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activerecord
         | 
| @@ -127,6 +127,10 @@ files: | |
| 127 127 | 
             
            - lib/acts_as_recursive_tree/builders/descendants.rb
         | 
| 128 128 | 
             
            - lib/acts_as_recursive_tree/builders/leaves.rb
         | 
| 129 129 | 
             
            - lib/acts_as_recursive_tree/builders/relation_builder.rb
         | 
| 130 | 
            +
            - lib/acts_as_recursive_tree/builders/strategy.rb
         | 
| 131 | 
            +
            - lib/acts_as_recursive_tree/builders/strategy/join.rb
         | 
| 132 | 
            +
            - lib/acts_as_recursive_tree/builders/strategy/subselect.rb
         | 
| 133 | 
            +
            - lib/acts_as_recursive_tree/config.rb
         | 
| 130 134 | 
             
            - lib/acts_as_recursive_tree/model.rb
         | 
| 131 135 | 
             
            - lib/acts_as_recursive_tree/options.rb
         | 
| 132 136 | 
             
            - lib/acts_as_recursive_tree/options/depth_condition.rb
         | 
| @@ -165,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 165 169 | 
             
                  version: '0'
         | 
| 166 170 | 
             
            requirements: []
         | 
| 167 171 | 
             
            rubyforge_project: 
         | 
| 168 | 
            -
            rubygems_version: 2.6 | 
| 172 | 
            +
            rubygems_version: 2.7.6
         | 
| 169 173 | 
             
            signing_key: 
         | 
| 170 174 | 
             
            specification_version: 4
         | 
| 171 175 | 
             
            summary: Drop in replacement for acts_as_tree but using recursive queries
         | 
| @@ -180,4 +184,3 @@ test_files: | |
| 180 184 | 
             
            - spec/model/relation_spec.rb
         | 
| 181 185 | 
             
            - spec/spec_helper.rb
         | 
| 182 186 | 
             
            - spec/values_spec.rb
         | 
| 183 | 
            -
            has_rdoc: 
         |