arel-helpers 2.10.0 → 2.13.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 +4 -4
 - data/Gemfile +3 -2
 - data/README.md +29 -3
 - data/arel-helpers.gemspec +12 -9
 - data/lib/arel-helpers/join_association.rb +61 -34
 - data/lib/arel-helpers/query_builder.rb +16 -1
 - data/lib/arel-helpers/version.rb +1 -1
 - data/spec/aliases_spec.rb +5 -7
 - data/spec/arel_table_spec.rb +11 -13
 - data/spec/env/models.rb +2 -6
 - data/spec/internal/config/database.yml +3 -0
 - data/spec/internal/db/combustion_test.sqlite +0 -0
 - data/spec/internal/db/schema.rb +34 -0
 - data/spec/internal/log/test.log +530 -0
 - data/spec/join_association_spec.rb +101 -57
 - data/spec/query_builder_spec.rb +39 -18
 - data/spec/spec_helper.rb +10 -19
 - metadata +57 -13
 - data/spec/env/migrations.rb +0 -75
 - data/spec/env.rb +0 -44
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: afe6ddeb4e41b56b59f08d6b2ac09bfd832e66b995355169b756ed22d11a2136
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 944d2e1730143abe055f2dad7efe9d01b9ddafabab2080811714d72405177446
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 5f03ab5b864494bcc5cfb2bc7558c315a18e6460cd815c34855b2b3f0ac9d2696a49b3bd3755543c9124e2ef0667e4d774ae4164cd0317705f74556696c6cfc3
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: e3f704bb25be566eb5797f81804d4446b9c3c96b5df84129afb5bdeec16b91fb420d2cc7ff901648e8dab03a818d2036a5288fa6a11c95d14231b6cd9ed74b97
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -1,2 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            source 'https://rubygems.org'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gemspec
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            
         
     | 
| 
       1 
2 
     | 
    
         | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            ## arel-helpers [](http://travis-ci.org/camertron/arel-helpers)
         
     | 
| 
      
 3 
     | 
    
         
            +
            ## arel-helpers
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            Useful tools to help construct database queries with ActiveRecord and Arel.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
         @@ -187,9 +187,35 @@ PostQueryBuilder.new 
     | 
|
| 
       187 
187 
     | 
    
         
             
              .since_yesterday
         
     | 
| 
       188 
188 
     | 
    
         
             
            ```
         
     | 
| 
       189 
189 
     | 
    
         | 
| 
      
 190 
     | 
    
         
            +
            #### Conditional reflections
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            If you have parts of a query that should only be added under certain conditions you can return `reflect(query)` from your method. E.g:
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 195 
     | 
    
         
            +
              def with_comments_by(usernames)
         
     | 
| 
      
 196 
     | 
    
         
            +
                if usernames
         
     | 
| 
      
 197 
     | 
    
         
            +
                  reflect(
         
     | 
| 
      
 198 
     | 
    
         
            +
                    query.where(post[:title].matches("%#{title}%"))
         
     | 
| 
      
 199 
     | 
    
         
            +
                  )
         
     | 
| 
      
 200 
     | 
    
         
            +
                else
         
     | 
| 
      
 201 
     | 
    
         
            +
                  reflect(query)
         
     | 
| 
      
 202 
     | 
    
         
            +
                end
         
     | 
| 
      
 203 
     | 
    
         
            +
              end
         
     | 
| 
      
 204 
     | 
    
         
            +
            ```
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
            This can become repetitive, and as an alternative you can choose to prepend `not_nil` to your method definition:
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 209 
     | 
    
         
            +
              class PostQueryBuilder < ArelHelpers::QueryBuilder
         
     | 
| 
      
 210 
     | 
    
         
            +
                not_nil def with_comments_by(usernames)
         
     | 
| 
      
 211 
     | 
    
         
            +
                  reflect(query.where(post[:title].matches("%#{title}%"))) if usernames
         
     | 
| 
      
 212 
     | 
    
         
            +
                end
         
     | 
| 
      
 213 
     | 
    
         
            +
              end
         
     | 
| 
      
 214 
     | 
    
         
            +
            ```
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
       190 
216 
     | 
    
         
             
            ## Requirements
         
     | 
| 
       191 
217 
     | 
    
         | 
| 
       192 
     | 
    
         
            -
            Requires ActiveRecord >= 3.1.0, <  
     | 
| 
      
 218 
     | 
    
         
            +
            Requires ActiveRecord >= 3.1.0, < 7. Depends on SQLite for testing purposes.
         
     | 
| 
       193 
219 
     | 
    
         | 
| 
       194 
220 
     | 
    
         
             
            ## Running Tests
         
     | 
| 
       195 
221 
     | 
    
         | 
    
        data/arel-helpers.gemspec
    CHANGED
    
    | 
         @@ -1,23 +1,26 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'arel-helpers/version'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       5 
     | 
    
         
            -
              s.name     =  
     | 
| 
      
 5 
     | 
    
         
            +
              s.name     = 'arel-helpers'
         
     | 
| 
       6 
6 
     | 
    
         
             
              s.version  = ::ArelHelpers::VERSION
         
     | 
| 
       7 
     | 
    
         
            -
              s.authors  = [ 
     | 
| 
       8 
     | 
    
         
            -
              s.email    = [ 
     | 
| 
       9 
     | 
    
         
            -
              s.homepage =  
     | 
| 
      
 7 
     | 
    
         
            +
              s.authors  = ['Cameron Dutro']
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.email    = ['camertron@gmail.com']
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.homepage = 'https://github.com/camertron/arel-helpers'
         
     | 
| 
       10 
10 
     | 
    
         
             
              s.license  = 'MIT'
         
     | 
| 
       11 
     | 
    
         
            -
              s.description = s.summary =  
     | 
| 
      
 11 
     | 
    
         
            +
              s.description = s.summary = 'Useful tools to help construct database queries with ActiveRecord and Arel.'
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
              s.platform = Gem::Platform::RUBY
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
              s.add_dependency 'activerecord', '>= 3.1.0', '< 7'
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
      
 17 
     | 
    
         
            +
              s.add_development_dependency 'appraisal'
         
     | 
| 
      
 18 
     | 
    
         
            +
              s.add_development_dependency 'combustion', '~> 1.3'
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.add_development_dependency 'database_cleaner', '~> 1.8'
         
     | 
| 
       17 
20 
     | 
    
         
             
              s.add_development_dependency 'rake', '~> 10.0'
         
     | 
| 
       18 
     | 
    
         
            -
              s.add_development_dependency 'rspec', '~>  
     | 
| 
       19 
     | 
    
         
            -
              s.add_development_dependency ' 
     | 
| 
      
 21 
     | 
    
         
            +
              s.add_development_dependency 'rspec', '~> 3'
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_development_dependency 'sqlite3', '~> 1.4.0'
         
     | 
| 
       20 
23 
     | 
    
         | 
| 
       21 
24 
     | 
    
         
             
              s.require_path = 'lib'
         
     | 
| 
       22 
     | 
    
         
            -
              s.files = Dir[ 
     | 
| 
      
 25 
     | 
    
         
            +
              s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'History.txt', 'README.md', 'Rakefile', 'arel-helpers.gemspec']
         
     | 
| 
       23 
26 
     | 
    
         
             
            end
         
     | 
| 
         @@ -18,7 +18,9 @@ module ArelHelpers 
     | 
|
| 
       18 
18 
     | 
    
         
             
                  # This method encapsulates that functionality and yields an intermediate object for chaining.
         
     | 
| 
       19 
19 
     | 
    
         
             
                  # It also allows you to use an outer join instead of the default inner via the join_type arg.
         
     | 
| 
       20 
20 
     | 
    
         
             
                  def join_association(table, association, join_type = Arel::Nodes::InnerJoin, options = {}, &block)
         
     | 
| 
       21 
     | 
    
         
            -
                    if version >= '6. 
     | 
| 
      
 21 
     | 
    
         
            +
                    if version >= '6.1.0'
         
     | 
| 
      
 22 
     | 
    
         
            +
                      join_association_6_1_0(table, association, join_type, options, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    elsif version >= '6.0.0'
         
     | 
| 
       22 
24 
     | 
    
         
             
                      join_association_6_0_0(table, association, join_type, options, &block)
         
     | 
| 
       23 
25 
     | 
    
         
             
                    elsif version >= '5.2.1'
         
     | 
| 
       24 
26 
     | 
    
         
             
                      join_association_5_2_1(table, association, join_type, options, &block)
         
     | 
| 
         @@ -42,7 +44,7 @@ module ArelHelpers 
     | 
|
| 
       42 
44 
     | 
    
         
             
                  end
         
     | 
| 
       43 
45 
     | 
    
         | 
| 
       44 
46 
     | 
    
         
             
                  def join_association_3_1(table, association, join_type, options = {})
         
     | 
| 
       45 
     | 
    
         
            -
                    aliases = options.fetch(:aliases,  
     | 
| 
      
 47 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       46 
48 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       47 
49 
     | 
    
         
             
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
         
     | 
| 
       48 
50 
     | 
    
         
             
                    manager = Arel::SelectManager.new(table)
         
     | 
| 
         @@ -53,12 +55,9 @@ module ArelHelpers 
     | 
|
| 
       53 
55 
     | 
    
         
             
                    end
         
     | 
| 
       54 
56 
     | 
    
         | 
| 
       55 
57 
     | 
    
         
             
                    manager.join_sources.map do |assoc|
         
     | 
| 
       56 
     | 
    
         
            -
                       
     | 
| 
       57 
     | 
    
         
            -
                        assoc.left.table_alias = found_alias.name
         
     | 
| 
       58 
     | 
    
         
            -
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
                      assoc.left.table_alias = aliases[assoc.left.name].name if aliases.key?(assoc.left.name)
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                      if block_given?
         
     | 
| 
       61 
     | 
    
         
            -
                        # yield |assoc_name, join_conditions|
         
     | 
| 
       62 
61 
     | 
    
         
             
                        right = yield assoc.left.name.to_sym, assoc.right
         
     | 
| 
       63 
62 
     | 
    
         
             
                        assoc.class.new(assoc.left, right)
         
     | 
| 
       64 
63 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -68,7 +67,7 @@ module ArelHelpers 
     | 
|
| 
       68 
67 
     | 
    
         
             
                  end
         
     | 
| 
       69 
68 
     | 
    
         | 
| 
       70 
69 
     | 
    
         
             
                  def join_association_4_1(table, association, join_type, options = {})
         
     | 
| 
       71 
     | 
    
         
            -
                    aliases = options.fetch(:aliases,  
     | 
| 
      
 70 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       72 
71 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       73 
72 
     | 
    
         
             
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
         
     | 
| 
       74 
73 
     | 
    
         | 
| 
         @@ -79,9 +78,7 @@ module ArelHelpers 
     | 
|
| 
       79 
78 
     | 
    
         
             
                        constraint.right
         
     | 
| 
       80 
79 
     | 
    
         
             
                      end
         
     | 
| 
       81 
80 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                       
     | 
| 
       83 
     | 
    
         
            -
                        constraint.left.table_alias = found_alias.name
         
     | 
| 
       84 
     | 
    
         
            -
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      constraint.left.table_alias = aliases[constraint.left.name].name if aliases.key?(constraint.left.name)
         
     | 
| 
       85 
82 
     | 
    
         | 
| 
       86 
83 
     | 
    
         
             
                      join_type.new(constraint.left, right)
         
     | 
| 
       87 
84 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -93,7 +90,7 @@ module ArelHelpers 
     | 
|
| 
       93 
90 
     | 
    
         
             
                  # dynamically. To get around the problem, this method must return
         
     | 
| 
       94 
91 
     | 
    
         
             
                  # a string.
         
     | 
| 
       95 
92 
     | 
    
         
             
                  def join_association_4_2(table, association, join_type, options = {})
         
     | 
| 
       96 
     | 
    
         
            -
                    aliases = options.fetch(:aliases, [])
         
     | 
| 
      
 93 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       97 
94 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       98 
95 
     | 
    
         
             
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
         
     | 
| 
       99 
96 
     | 
    
         | 
| 
         @@ -111,9 +108,7 @@ module ArelHelpers 
     | 
|
| 
       111 
108 
     | 
    
         
             
                          join.right
         
     | 
| 
       112 
109 
     | 
    
         
             
                        end
         
     | 
| 
       113 
110 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                         
     | 
| 
       115 
     | 
    
         
            -
                          join.left.table_alias = found_alias.name
         
     | 
| 
       116 
     | 
    
         
            -
                        end
         
     | 
| 
      
 111 
     | 
    
         
            +
                        join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name)
         
     | 
| 
       117 
112 
     | 
    
         | 
| 
       118 
113 
     | 
    
         
             
                        join_type.new(join.left, right)
         
     | 
| 
       119 
114 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -127,7 +122,7 @@ module ArelHelpers 
     | 
|
| 
       127 
122 
     | 
    
         
             
                  end
         
     | 
| 
       128 
123 
     | 
    
         | 
| 
       129 
124 
     | 
    
         
             
                  def join_association_5_0(table, association, join_type, options = {})
         
     | 
| 
       130 
     | 
    
         
            -
                    aliases = options.fetch(:aliases, [])
         
     | 
| 
      
 125 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       131 
126 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       132 
127 
     | 
    
         
             
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
         
     | 
| 
       133 
128 
     | 
    
         | 
| 
         @@ -146,9 +141,7 @@ module ArelHelpers 
     | 
|
| 
       146 
141 
     | 
    
         
             
                          join.right
         
     | 
| 
       147 
142 
     | 
    
         
             
                        end
         
     | 
| 
       148 
143 
     | 
    
         | 
| 
       149 
     | 
    
         
            -
                         
     | 
| 
       150 
     | 
    
         
            -
                          join.left.table_alias = found_alias.name
         
     | 
| 
       151 
     | 
    
         
            -
                        end
         
     | 
| 
      
 144 
     | 
    
         
            +
                        join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name)
         
     | 
| 
       152 
145 
     | 
    
         | 
| 
       153 
146 
     | 
    
         
             
                        join_type.new(join.left, right)
         
     | 
| 
       154 
147 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -162,7 +155,7 @@ module ArelHelpers 
     | 
|
| 
       162 
155 
     | 
    
         
             
                  end
         
     | 
| 
       163 
156 
     | 
    
         | 
| 
       164 
157 
     | 
    
         
             
                  def join_association_5_2(table, association, join_type, options = {})
         
     | 
| 
       165 
     | 
    
         
            -
                    aliases = options.fetch(:aliases, [])
         
     | 
| 
      
 158 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       166 
159 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       167 
160 
     | 
    
         | 
| 
       168 
161 
     | 
    
         
             
                    alias_tracker = ActiveRecord::Associations::AliasTracker.create(
         
     | 
| 
         @@ -182,16 +175,14 @@ module ArelHelpers 
     | 
|
| 
       182 
175 
     | 
    
         
             
                        join.right
         
     | 
| 
       183 
176 
     | 
    
         
             
                      end
         
     | 
| 
       184 
177 
     | 
    
         | 
| 
       185 
     | 
    
         
            -
                       
     | 
| 
       186 
     | 
    
         
            -
                        join.left.table_alias = found_alias.name
         
     | 
| 
       187 
     | 
    
         
            -
                      end
         
     | 
| 
      
 178 
     | 
    
         
            +
                      join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name)
         
     | 
| 
       188 
179 
     | 
    
         | 
| 
       189 
180 
     | 
    
         
             
                      join_type.new(join.left, right)
         
     | 
| 
       190 
181 
     | 
    
         
             
                    end
         
     | 
| 
       191 
182 
     | 
    
         
             
                  end
         
     | 
| 
       192 
183 
     | 
    
         | 
| 
       193 
184 
     | 
    
         
             
                  def join_association_5_2_1(table, association, join_type, options = {})
         
     | 
| 
       194 
     | 
    
         
            -
                    aliases = options.fetch(:aliases, [])
         
     | 
| 
      
 185 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       195 
186 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       196 
187 
     | 
    
         | 
| 
       197 
188 
     | 
    
         
             
                    alias_tracker = ActiveRecord::Associations::AliasTracker.create(
         
     | 
| 
         @@ -211,16 +202,14 @@ module ArelHelpers 
     | 
|
| 
       211 
202 
     | 
    
         
             
                        join.right
         
     | 
| 
       212 
203 
     | 
    
         
             
                      end
         
     | 
| 
       213 
204 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
                       
     | 
| 
       215 
     | 
    
         
            -
                        join.left.table_alias = found_alias.name
         
     | 
| 
       216 
     | 
    
         
            -
                      end
         
     | 
| 
      
 205 
     | 
    
         
            +
                      join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name)
         
     | 
| 
       217 
206 
     | 
    
         | 
| 
       218 
207 
     | 
    
         
             
                      join_type.new(join.left, right)
         
     | 
| 
       219 
208 
     | 
    
         
             
                    end
         
     | 
| 
       220 
209 
     | 
    
         
             
                  end
         
     | 
| 
       221 
210 
     | 
    
         | 
| 
       222 
211 
     | 
    
         
             
                  def join_association_6_0_0(table, association, join_type, options = {})
         
     | 
| 
       223 
     | 
    
         
            -
                    aliases = options.fetch(:aliases, [])
         
     | 
| 
      
 212 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
       224 
213 
     | 
    
         
             
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
       225 
214 
     | 
    
         | 
| 
       226 
215 
     | 
    
         
             
                    alias_tracker = ActiveRecord::Associations::AliasTracker.create(
         
     | 
| 
         @@ -240,14 +229,56 @@ module ArelHelpers 
     | 
|
| 
       240 
229 
     | 
    
         
             
                        join.right
         
     | 
| 
       241 
230 
     | 
    
         
             
                      end
         
     | 
| 
       242 
231 
     | 
    
         | 
| 
       243 
     | 
    
         
            -
                       
     | 
| 
       244 
     | 
    
         
            -
                        join.left.table_alias = found_alias.name
         
     | 
| 
       245 
     | 
    
         
            -
                      end
         
     | 
| 
      
 232 
     | 
    
         
            +
                      join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name)
         
     | 
| 
       246 
233 
     | 
    
         | 
| 
       247 
234 
     | 
    
         
             
                      join_type.new(join.left, right)
         
     | 
| 
       248 
235 
     | 
    
         
             
                    end
         
     | 
| 
       249 
236 
     | 
    
         
             
                  end
         
     | 
| 
       250 
237 
     | 
    
         | 
| 
      
 238 
     | 
    
         
            +
                  def join_association_6_1_0(table, association, join_type, options = {})
         
     | 
| 
      
 239 
     | 
    
         
            +
                    aliases = options.fetch(:aliases, []).index_by(&:table_name)
         
     | 
| 
      
 240 
     | 
    
         
            +
                    associations = association.is_a?(Array) ? association : [association]
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                    alias_tracker = ActiveRecord::Associations::AliasTracker.create(
         
     | 
| 
      
 243 
     | 
    
         
            +
                      table.connection, table.name, {}
         
     | 
| 
      
 244 
     | 
    
         
            +
                    )
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(
         
     | 
| 
      
 247 
     | 
    
         
            +
                      table, table.arel_table, associations, join_type
         
     | 
| 
      
 248 
     | 
    
         
            +
                    )
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                    constraints = join_dependency.join_constraints([], alias_tracker, [])
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                    constraints.map do |join|
         
     | 
| 
      
 253 
     | 
    
         
            +
                      apply_aliases(join, aliases)
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                      right = if block_given?
         
     | 
| 
      
 256 
     | 
    
         
            +
                                yield join.left.name.to_sym, join.right
         
     | 
| 
      
 257 
     | 
    
         
            +
                              else
         
     | 
| 
      
 258 
     | 
    
         
            +
                                join.right
         
     | 
| 
      
 259 
     | 
    
         
            +
                              end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                      join_type.new(join.left, right)
         
     | 
| 
      
 262 
     | 
    
         
            +
                    end
         
     | 
| 
      
 263 
     | 
    
         
            +
                  end
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                  def apply_aliases(node, aliases)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    case node
         
     | 
| 
      
 267 
     | 
    
         
            +
                    when Arel::Nodes::Join
         
     | 
| 
      
 268 
     | 
    
         
            +
                      node.left = aliases[node.left.name] || node.left
         
     | 
| 
      
 269 
     | 
    
         
            +
                      apply_aliases(node.right, aliases)
         
     | 
| 
      
 270 
     | 
    
         
            +
                    when Arel::Attributes::Attribute
         
     | 
| 
      
 271 
     | 
    
         
            +
                      node.relation = aliases[node.relation.name] || node.relation
         
     | 
| 
      
 272 
     | 
    
         
            +
                    when Arel::Nodes::And
         
     | 
| 
      
 273 
     | 
    
         
            +
                      node.children.each { |child| apply_aliases(child, aliases) }
         
     | 
| 
      
 274 
     | 
    
         
            +
                    when Arel::Nodes::Unary
         
     | 
| 
      
 275 
     | 
    
         
            +
                      apply_aliases(node.value, aliases)
         
     | 
| 
      
 276 
     | 
    
         
            +
                    when Arel::Nodes::Binary
         
     | 
| 
      
 277 
     | 
    
         
            +
                      apply_aliases(node.left, aliases)
         
     | 
| 
      
 278 
     | 
    
         
            +
                      apply_aliases(node.right, aliases)
         
     | 
| 
      
 279 
     | 
    
         
            +
                    end
         
     | 
| 
      
 280 
     | 
    
         
            +
                  end
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
       251 
282 
     | 
    
         
             
                  private
         
     | 
| 
       252 
283 
     | 
    
         | 
| 
       253 
284 
     | 
    
         
             
                  def to_sql(node, table, binds)
         
     | 
| 
         @@ -255,10 +286,6 @@ module ArelHelpers 
     | 
|
| 
       255 
286 
     | 
    
         
             
                    collect = visitor.accept(node, Arel::Collectors::Bind.new)
         
     | 
| 
       256 
287 
     | 
    
         
             
                    collect.substitute_binds(binds).join
         
     | 
| 
       257 
288 
     | 
    
         
             
                  end
         
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
     | 
    
         
            -
                  def find_alias(name, aliases)
         
     | 
| 
       260 
     | 
    
         
            -
                    aliases.find { |a| a.table_name == name }
         
     | 
| 
       261 
     | 
    
         
            -
                  end
         
     | 
| 
       262 
289 
     | 
    
         
             
                end
         
     | 
| 
       263 
290 
     | 
    
         
             
              end
         
     | 
| 
       264 
291 
     | 
    
         
             
            end
         
     | 
| 
         @@ -9,13 +9,28 @@ module ArelHelpers 
     | 
|
| 
       9 
9 
     | 
    
         
             
                include Enumerable
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                attr_reader :query
         
     | 
| 
       12 
     | 
    
         
            -
                def_delegators :@query, :to_a, :to_sql, :each
         
     | 
| 
      
 12 
     | 
    
         
            +
                def_delegators :@query, :to_a, :to_sql, :each, :empty?, :size
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                TERMINAL_METHODS = [:count, :first, :last]
         
     | 
| 
       15 
15 
     | 
    
         
             
                TERMINAL_METHODS << :pluck if ActiveRecord::VERSION::MAJOR >= 4
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                def_delegators :@query, *TERMINAL_METHODS
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
      
 19 
     | 
    
         
            +
                def self.not_nil(name)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  mod = Module.new do
         
     | 
| 
      
 21 
     | 
    
         
            +
                    define_method(name) do |*args, **kwargs|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      if (value = super(*args, **kwargs))
         
     | 
| 
      
 23 
     | 
    
         
            +
                        value
         
     | 
| 
      
 24 
     | 
    
         
            +
                      else
         
     | 
| 
      
 25 
     | 
    
         
            +
                        reflect(query)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  prepend mod
         
     | 
| 
      
 31 
     | 
    
         
            +
                  name
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       19 
34 
     | 
    
         
             
                def initialize(query)
         
     | 
| 
       20 
35 
     | 
    
         
             
                  @query = query
         
     | 
| 
       21 
36 
     | 
    
         
             
                end
         
     | 
    
        data/lib/arel-helpers/version.rb
    CHANGED
    
    
    
        data/spec/aliases_spec.rb
    CHANGED
    
    | 
         @@ -1,17 +1,15 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # encoding: UTF-8
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            require 'spec_helper'
         
     | 
| 
       4 
2 
     | 
    
         | 
| 
       5 
3 
     | 
    
         
             
            describe ArelHelpers::Aliases do
         
     | 
| 
       6 
     | 
    
         
            -
              describe  
     | 
| 
       7 
     | 
    
         
            -
                it  
     | 
| 
      
 4 
     | 
    
         
            +
              describe '#aliased_as' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                it 'yields an alias when passed a block' do
         
     | 
| 
       8 
6 
     | 
    
         
             
                  Post.aliased_as('foo') do |foo_alias|
         
     | 
| 
       9 
7 
     | 
    
         
             
                    expect(foo_alias).to be_a(Arel::Nodes::TableAlias)
         
     | 
| 
       10 
8 
     | 
    
         
             
                    expect(foo_alias.name).to eq('foo')
         
     | 
| 
       11 
9 
     | 
    
         
             
                  end
         
     | 
| 
       12 
10 
     | 
    
         
             
                end
         
     | 
| 
       13 
11 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                it  
     | 
| 
      
 12 
     | 
    
         
            +
                it 'is capable of yielding multiple aliases' do
         
     | 
| 
       15 
13 
     | 
    
         
             
                  Post.aliased_as('foo', 'bar') do |foo_alias, bar_alias|
         
     | 
| 
       16 
14 
     | 
    
         
             
                    expect(foo_alias).to be_a(Arel::Nodes::TableAlias)
         
     | 
| 
       17 
15 
     | 
    
         
             
                    expect(foo_alias.name).to eq('foo')
         
     | 
| 
         @@ -21,14 +19,14 @@ describe ArelHelpers::Aliases do 
     | 
|
| 
       21 
19 
     | 
    
         
             
                  end
         
     | 
| 
       22 
20 
     | 
    
         
             
                end
         
     | 
| 
       23 
21 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                it  
     | 
| 
      
 22 
     | 
    
         
            +
                it 'returns an alias when not passed a block' do
         
     | 
| 
       25 
23 
     | 
    
         
             
                  aliases = Post.aliased_as('foo')
         
     | 
| 
       26 
24 
     | 
    
         
             
                  expect(aliases.size).to eq(1)
         
     | 
| 
       27 
25 
     | 
    
         
             
                  expect(aliases[0]).to be_a(Arel::Nodes::TableAlias)
         
     | 
| 
       28 
26 
     | 
    
         
             
                  expect(aliases[0].name).to eq('foo')
         
     | 
| 
       29 
27 
     | 
    
         
             
                end
         
     | 
| 
       30 
28 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                it  
     | 
| 
      
 29 
     | 
    
         
            +
                it 'is capable of returning multiple aliases' do
         
     | 
| 
       32 
30 
     | 
    
         
             
                  aliases = Post.aliased_as('foo', 'bar')
         
     | 
| 
       33 
31 
     | 
    
         
             
                  expect(aliases.size).to eq(2)
         
     | 
| 
       34 
32 
     | 
    
         | 
    
        data/spec/arel_table_spec.rb
    CHANGED
    
    | 
         @@ -1,30 +1,28 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # encoding: UTF-8
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            require 'spec_helper'
         
     | 
| 
       4 
2 
     | 
    
         | 
| 
       5 
3 
     | 
    
         
             
            describe ArelHelpers::ArelTable do
         
     | 
| 
       6 
     | 
    
         
            -
              it  
     | 
| 
      
 4 
     | 
    
         
            +
              it 'should add the [] function to the model and allow attribute access' do
         
     | 
| 
       7 
5 
     | 
    
         
             
                Post[:id].tap do |post_id|
         
     | 
| 
       8 
     | 
    
         
            -
                  post_id. 
     | 
| 
       9 
     | 
    
         
            -
                  post_id.name. 
     | 
| 
       10 
     | 
    
         
            -
                  post_id.relation.name. 
     | 
| 
      
 6 
     | 
    
         
            +
                  expect(post_id).to be_a Arel::Attribute
         
     | 
| 
      
 7 
     | 
    
         
            +
                  expect(post_id.name.to_s).to eq 'id'
         
     | 
| 
      
 8 
     | 
    
         
            +
                  expect(post_id.relation.name).to eq 'posts'
         
     | 
| 
       11 
9 
     | 
    
         
             
                end
         
     | 
| 
       12 
10 
     | 
    
         
             
              end
         
     | 
| 
       13 
11 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
              it  
     | 
| 
      
 12 
     | 
    
         
            +
              it 'should not interfere with associations' do
         
     | 
| 
       15 
13 
     | 
    
         
             
                post = Post.create(title: "I'm a little teapot")
         
     | 
| 
       16 
     | 
    
         
            -
                post.comments[0]. 
     | 
| 
      
 14 
     | 
    
         
            +
                expect(post.comments[0]).to be_nil
         
     | 
| 
       17 
15 
     | 
    
         
             
              end
         
     | 
| 
       18 
16 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
              it  
     | 
| 
      
 17 
     | 
    
         
            +
              it 'should allow retrieving associated records' do
         
     | 
| 
       20 
18 
     | 
    
         
             
                post = Post.create(title: "I'm a little teapot")
         
     | 
| 
       21 
19 
     | 
    
         
             
                comment = post.comments.create
         
     | 
| 
       22 
     | 
    
         
            -
                post.reload.comments[0].id. 
     | 
| 
      
 20 
     | 
    
         
            +
                expect(post.reload.comments[0].id).to eq comment.id
         
     | 
| 
       23 
21 
     | 
    
         
             
              end
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
              it  
     | 
| 
       26 
     | 
    
         
            -
                Post.all[0]. 
     | 
| 
      
 23 
     | 
    
         
            +
              it 'does not interfere with ActiveRecord::Relation objects' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                expect(Post.all[0]).to be_nil
         
     | 
| 
       27 
25 
     | 
    
         
             
                p = Post.create(title: 'foo')
         
     | 
| 
       28 
     | 
    
         
            -
                Post.all[0].id. 
     | 
| 
      
 26 
     | 
    
         
            +
                expect(Post.all[0].id).to eq p.id
         
     | 
| 
       29 
27 
     | 
    
         
             
              end
         
     | 
| 
       30 
28 
     | 
    
         
             
            end
         
     | 
    
        data/spec/env/models.rb
    CHANGED
    
    | 
         @@ -1,5 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # encoding: UTF-8
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            class Post < ActiveRecord::Base
         
     | 
| 
       4 
2 
     | 
    
         
             
              include ArelHelpers::ArelTable
         
     | 
| 
       5 
3 
     | 
    
         
             
              include ArelHelpers::Aliases
         
     | 
| 
         @@ -44,12 +42,10 @@ end 
     | 
|
| 
       44 
42 
     | 
    
         | 
| 
       45 
43 
     | 
    
         
             
            class Location < ActiveRecord::Base
         
     | 
| 
       46 
44 
     | 
    
         
             
              has_many :card_locations
         
     | 
| 
       47 
     | 
    
         
            -
              has_many :community_tickets,  
     | 
| 
       48 
     | 
    
         
            -
                through: :card_locations, source: :card, source_type: 'CommunityTicket'
         
     | 
| 
       49 
     | 
    
         
            -
              }
         
     | 
| 
      
 45 
     | 
    
         
            +
              has_many :community_tickets, through: :card_locations, source: :card, source_type: 'CommunityTicket'
         
     | 
| 
       50 
46 
     | 
    
         
             
            end
         
     | 
| 
       51 
47 
     | 
    
         | 
| 
       52 
48 
     | 
    
         
             
            class CommunityTicket < ActiveRecord::Base
         
     | 
| 
       53 
     | 
    
         
            -
              has_many :card_locations, as: :card 
     | 
| 
      
 49 
     | 
    
         
            +
              has_many :card_locations, as: :card
         
     | 
| 
       54 
50 
     | 
    
         
             
              has_many :locations, through: :card_locations
         
     | 
| 
       55 
51 
     | 
    
         
             
            end
         
     | 
| 
         Binary file 
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ActiveRecord::Schema.define do
         
     | 
| 
      
 4 
     | 
    
         
            +
              create_table :posts do |t|
         
     | 
| 
      
 5 
     | 
    
         
            +
                t.column :title, :string
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              create_table :comments do |t|
         
     | 
| 
      
 9 
     | 
    
         
            +
                t.references :post
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              create_table :authors do |t|
         
     | 
| 
      
 13 
     | 
    
         
            +
                t.references :comment
         
     | 
| 
      
 14 
     | 
    
         
            +
                t.references :collab_posts
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              create_table :favorites do |t|
         
     | 
| 
      
 18 
     | 
    
         
            +
                t.references :post
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              create_table :collab_posts do |t|
         
     | 
| 
      
 22 
     | 
    
         
            +
                t.references :authors
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              create_table :cards
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              create_table :card_locations do |t|
         
     | 
| 
      
 28 
     | 
    
         
            +
                t.references :location
         
     | 
| 
      
 29 
     | 
    
         
            +
                t.references :card, polymorphic: true
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              create_table :locations
         
     | 
| 
      
 33 
     | 
    
         
            +
              create_table :community_tickets
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     |