acts_as_recursive_tree 2.0.0 → 2.0.1
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +37 -0
- data/lib/acts_as_recursive_tree/builders/ancestors.rb +1 -1
- data/lib/acts_as_recursive_tree/builders/descendants.rb +1 -1
- data/lib/acts_as_recursive_tree/builders/leaves.rb +3 -3
- data/lib/acts_as_recursive_tree/builders/relation_builder.rb +39 -27
- data/lib/acts_as_recursive_tree/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ffd168c454a68c9fdc6ae7fb32b705bdaba8964f
         | 
| 4 | 
            +
              data.tar.gz: 2367e9b864ee904abc49198936f5afb59bb2d46b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4c4e359bbc497ff24f6ba6e8ccfbd846ce17178c0842850d3e3a0bee43e7d15cd8cd6a0a40072aa74d48e538d4a4dc892be743a677c34c39b7280348588ed74e
         | 
| 7 | 
            +
              data.tar.gz: 12c7f7bac25c0547573d66bc8efa7b6e6ea4e3815f3490c929b8551886512c2cef6619f48a954d02a89518a79ac4da412d66fb69973b8321245d9bd7049952ba
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -164,7 +164,44 @@ node_instance.descendants{ |opts| opts.ensure_ordering! } | |
| 164 164 |  | 
| 165 165 | 
             
            NOTE: if there are many descendants this may cause a severe increase in execution time! 
         | 
| 166 166 |  | 
| 167 | 
            +
            ## Single Table Inheritance (STI)
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            STI works out of the box. Consider following classes: 
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            ```ruby
         | 
| 172 | 
            +
            class Node  < ActiveRecord::Base
         | 
| 173 | 
            +
              recursive_tree
         | 
| 174 | 
            +
            end
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            class SubNode  < Node
         | 
| 167 177 |  | 
| 178 | 
            +
            end
         | 
| 179 | 
            +
            ```
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            When calling ClassMethods the results depend on the class on which you call the method:
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            ```ruby
         | 
| 184 | 
            +
            Node.descendants_of(123) # => returns Node and SubNode instances
         | 
| 185 | 
            +
            SubNode.descendants_of(123) # => returns SubNode instances only
         | 
| 186 | 
            +
            ```
         | 
| 187 | 
            +
             | 
| 188 | 
            +
            Instance Methods make no difference of the class from which they are called:
         | 
| 189 | 
            +
             | 
| 190 | 
            +
            ```ruby
         | 
| 191 | 
            +
            sub_node_instance.descendants # => returns Node and SubNode instances
         | 
| 192 | 
            +
            ```
         | 
| 193 | 
            +
             | 
| 194 | 
            +
             | 
| 195 | 
            +
            ## Known Issues
         | 
| 196 | 
            +
             | 
| 197 | 
            +
            When using PostgreSQL as underlying database system chances are good that you encounter following error message:
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            `
         | 
| 200 | 
            +
            ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR:  bind message supplies 1 parameters, but prepared statement "" requires 2
         | 
| 201 | 
            +
            `
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            This is a known ActiveRecord issue which should be fixed in Rails 5.2. Alternative 
         | 
| 204 | 
            +
             | 
| 168 205 |  | 
| 169 206 | 
             
            ## Contributing
         | 
| 170 207 |  | 
| @@ -6,10 +6,10 @@ module ActsAsRecursiveTree | |
| 6 6 | 
             
                    select_manager = super
         | 
| 7 7 |  | 
| 8 8 | 
             
                    select_manager.where(
         | 
| 9 | 
            -
                        travers_loc_table[ | 
| 9 | 
            +
                        travers_loc_table[primary_key].not_in(
         | 
| 10 10 | 
             
                            travers_loc_table.where(
         | 
| 11 | 
            -
                                travers_loc_table[ | 
| 12 | 
            -
                            ).project(travers_loc_table[ | 
| 11 | 
            +
                                travers_loc_table[parent_key].not_eq(nil)
         | 
| 12 | 
            +
                            ).project(travers_loc_table[parent_key])
         | 
| 13 13 | 
             
                        )
         | 
| 14 14 | 
             
                    )
         | 
| 15 15 | 
             
                    select_manager
         | 
| @@ -6,13 +6,16 @@ module ActsAsRecursiveTree | |
| 6 6 | 
             
                    new(klass, ids, exclude_ids: exclude_ids, &block).build
         | 
| 7 7 | 
             
                  end
         | 
| 8 8 |  | 
| 9 | 
            -
                  attr_reader :klass, :ids, :recursive_temp_table, :travers_loc_table
         | 
| 10 | 
            -
                  attr_reader :query_opts, :without_ids
         | 
| 9 | 
            +
                  attr_reader :klass, :ids, :recursive_temp_table, :travers_loc_table, :without_ids
         | 
| 11 10 | 
             
                  mattr_reader(:random) { Random.new }
         | 
| 12 11 |  | 
| 12 | 
            +
                  delegate :primary_key, :depth_column, :parent_key, :parent_type_column, to: :@config
         | 
| 13 | 
            +
                  delegate :depth_present?, :depth, :condition, :ensure_ordering, to: :@query_opts
         | 
| 14 | 
            +
             | 
| 13 15 | 
             
                  def initialize(klass, ids, exclude_ids: false, &block)
         | 
| 14 16 | 
             
                    @klass       = klass
         | 
| 15 | 
            -
                    @ | 
| 17 | 
            +
                    @config      = klass._recursive_tree_config
         | 
| 18 | 
            +
                    @ids         = ActsAsRecursiveTree::Options::Values.create(ids, @config)
         | 
| 16 19 | 
             
                    @without_ids = exclude_ids
         | 
| 17 20 |  | 
| 18 21 | 
             
                    @query_opts = get_query_options(block)
         | 
| @@ -34,15 +37,11 @@ module ActsAsRecursiveTree | |
| 34 37 | 
             
                    klass.arel_table
         | 
| 35 38 | 
             
                  end
         | 
| 36 39 |  | 
| 37 | 
            -
                  def config
         | 
| 38 | 
            -
                    klass._recursive_tree_config
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 40 | 
             
                  def build
         | 
| 42 41 | 
             
                    final_select_mgr = base_table.join(
         | 
| 43 42 | 
             
                      create_select_manger.as(recursive_temp_table.name)
         | 
| 44 43 | 
             
                    ).on(
         | 
| 45 | 
            -
                      base_table[ | 
| 44 | 
            +
                      base_table[primary_key].eq(recursive_temp_table[primary_key])
         | 
| 46 45 | 
             
                    )
         | 
| 47 46 |  | 
| 48 47 | 
             
                    relation = klass.joins(final_select_mgr.join_sources)
         | 
| @@ -56,18 +55,18 @@ module ActsAsRecursiveTree | |
| 56 55 |  | 
| 57 56 | 
             
                  def apply_except_id(relation)
         | 
| 58 57 | 
             
                    return relation unless without_ids
         | 
| 59 | 
            -
                    relation.where(ids.apply_negated_to(base_table[ | 
| 58 | 
            +
                    relation.where(ids.apply_negated_to(base_table[primary_key]))
         | 
| 60 59 | 
             
                  end
         | 
| 61 60 |  | 
| 62 61 | 
             
                  def apply_depth(relation)
         | 
| 63 | 
            -
                    return relation unless  | 
| 62 | 
            +
                    return relation unless depth_present?
         | 
| 64 63 |  | 
| 65 | 
            -
                    relation.where( | 
| 64 | 
            +
                    relation.where(depth.apply_to(recursive_temp_table[depth_column]))
         | 
| 66 65 | 
             
                  end
         | 
| 67 66 |  | 
| 68 67 | 
             
                  def apply_order(relation)
         | 
| 69 | 
            -
                    return relation unless  | 
| 70 | 
            -
                    relation.order(recursive_temp_table[ | 
| 68 | 
            +
                    return relation unless ensure_ordering
         | 
| 69 | 
            +
                    relation.order(recursive_temp_table[depth_column].asc)
         | 
| 71 70 | 
             
                  end
         | 
| 72 71 |  | 
| 73 72 | 
             
                  def create_select_manger
         | 
| @@ -82,34 +81,47 @@ module ActsAsRecursiveTree | |
| 82 81 | 
             
                  end
         | 
| 83 82 |  | 
| 84 83 | 
             
                  def build_base_select
         | 
| 85 | 
            -
                    id_node = base_table[ | 
| 84 | 
            +
                    id_node = base_table[primary_key]
         | 
| 86 85 |  | 
| 87 86 | 
             
                    base_table.where(
         | 
| 88 87 | 
             
                      ids.apply_to(id_node)
         | 
| 89 88 | 
             
                    ).project(
         | 
| 90 89 | 
             
                      id_node,
         | 
| 91 | 
            -
                      base_table[ | 
| 92 | 
            -
                      Arel.sql('0').as( | 
| 90 | 
            +
                      base_table[parent_key],
         | 
| 91 | 
            +
                      Arel.sql('0').as(depth_column.to_s)
         | 
| 93 92 | 
             
                    )
         | 
| 94 93 | 
             
                  end
         | 
| 95 94 |  | 
| 96 95 | 
             
                  def build_union_select
         | 
| 97 | 
            -
                     | 
| 98 | 
            -
             | 
| 99 | 
            -
                    )
         | 
| 96 | 
            +
                    join_condition = apply_parent_type_column(build_join_condition)
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    select_manager = base_table.join(travers_loc_table).on(join_condition)
         | 
| 100 99 |  | 
| 101 100 | 
             
                    # need to use ActiveRecord here for merging relation
         | 
| 102 | 
            -
                    relation =  | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 101 | 
            +
                    relation = build_base_join_select(select_manager)
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    relation = apply_query_opts_condition(relation)
         | 
| 104 | 
            +
                    relation.arel
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  def apply_parent_type_column(arel_condition)
         | 
| 108 | 
            +
                    return arel_condition unless parent_type_column.present?
         | 
| 109 | 
            +
                    arel_condition.and(base_table[parent_type_column].eq(klass.base_class))
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  def build_base_join_select(select_manager)
         | 
| 113 | 
            +
                    klass.select(
         | 
| 114 | 
            +
                      base_table[primary_key],
         | 
| 115 | 
            +
                      base_table[parent_key],
         | 
| 105 116 | 
             
                      Arel.sql(
         | 
| 106 | 
            -
                        (travers_loc_table[ | 
| 107 | 
            -
                      ).as( | 
| 117 | 
            +
                        (travers_loc_table[depth_column] + 1).to_sql
         | 
| 118 | 
            +
                      ).as(depth_column.to_s)
         | 
| 108 119 | 
             
                    ).unscope(where: :type).joins(select_manager.join_sources)
         | 
| 120 | 
            +
                  end
         | 
| 109 121 |  | 
| 110 | 
            -
             | 
| 111 | 
            -
                     | 
| 112 | 
            -
                    relation. | 
| 122 | 
            +
                  def apply_query_opts_condition(relation)
         | 
| 123 | 
            +
                    return relation unless condition.present?
         | 
| 124 | 
            +
                    relation.merge(condition)
         | 
| 113 125 | 
             
                  end
         | 
| 114 126 |  | 
| 115 127 | 
             
                  def build_join_condition
         | 
    
        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.0.1
         | 
| 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-01- | 
| 11 | 
            +
            date: 2018-01-23 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activerecord
         |