active_record_union 1.2.0 → 1.3.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/.travis.yml +3 -11
- data/README.md +9 -4
- data/lib/active_record_union/active_record/relation/union.rb +45 -26
- data/lib/active_record_union/version.rb +1 -1
- data/rails_4_2.gemfile +6 -1
- data/rails_5_0.gemfile +6 -1
- data/rails_5_1.gemfile +11 -0
- data/rails_5_2.gemfile +7 -0
- data/spec/union_spec.rb +5 -1
- metadata +5 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3b6908e8b32e304532e3b8405712ade67fab7e52
         | 
| 4 | 
            +
              data.tar.gz: 937298c6d470715b18510f2e317a7f3d735b2cf6
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8466c15bb3c268bbea28f49b3a85915e91f72bd43997462a4bd09a1da14ec9c85d5ca9621a6b7316ac04fe6949ccf4284bce854ed5b33c71bc492ca9bbd0cc9f
         | 
| 7 | 
            +
              data.tar.gz: a99a9d9c0c19e332d9b0c357310d886c72c5b7f629be97a0d8e2dcdc8d90dcb1605960f3a44a8dacdfe0749dc7dfe6f2571ebe27d63a6bcb1970e7798447a88f
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -2,18 +2,10 @@ language: ruby | |
| 2 2 | 
             
            addons:
         | 
| 3 3 | 
             
              postgresql: "9.4"
         | 
| 4 4 | 
             
            rvm:
         | 
| 5 | 
            -
              - 2.3. | 
| 6 | 
            -
              - 2.2.5
         | 
| 7 | 
            -
              - 2.1.8
         | 
| 8 | 
            -
              - 2.0.0
         | 
| 5 | 
            +
              - 2.3.6
         | 
| 9 6 | 
             
            gemfile:
         | 
| 10 7 | 
             
              - rails_4_2.gemfile
         | 
| 11 8 | 
             
              - rails_5_0.gemfile
         | 
| 12 | 
            -
             | 
| 13 | 
            -
               | 
| 14 | 
            -
              # Rails 5 requires Ruby 2.2+:
         | 
| 15 | 
            -
              - rvm: 2.1.8
         | 
| 16 | 
            -
                gemfile: rails_5_0.gemfile
         | 
| 17 | 
            -
              - rvm: 2.0.0
         | 
| 18 | 
            -
                gemfile: rails_5_0.gemfile
         | 
| 9 | 
            +
              - rails_5_1.gemfile
         | 
| 10 | 
            +
              - rails_5_2.gemfile
         | 
| 19 11 | 
             
            script: bundle exec rspec
         | 
    
        data/README.md
    CHANGED
    
    | @@ -17,6 +17,8 @@ user_1.posts.union(user_2.posts).union(Post.published) | |
| 17 17 | 
             
            user_1.posts.union_all(user_2.posts)
         | 
| 18 18 | 
             
            ```
         | 
| 19 19 |  | 
| 20 | 
            +
            ActiveRecordUnion is tested against Rails 4.2 and Rails 5.0. It may or may not work on Rails 4.0/4.1.
         | 
| 21 | 
            +
             | 
| 20 22 | 
             
            ## Installation
         | 
| 21 23 |  | 
| 22 24 | 
             
            Add this line to your application's Gemfile:
         | 
| @@ -127,7 +129,7 @@ SELECT "posts".* FROM ( | |
| 127 129 |  | 
| 128 130 | 
             
            There's a couple things to be aware of when using ActiveRecordUnion:
         | 
| 129 131 |  | 
| 130 | 
            -
            1. ActiveRecordUnion  | 
| 132 | 
            +
            1. ActiveRecordUnion will raise an error if you try to UNION any relations that do any preloading/eager-loading. There's no sensible way to do the preloading in the subselects. If enough people complain, maybe, we can change ActiveRecordUnion to let the queries run anyway but without preloading any records.
         | 
| 131 133 | 
             
            2. There's no easy way to get SQLite to allow ORDER BY in the UNION subselects. If you get a syntax error, you can either write `my_relation.reorder(nil).union(other.reorder(nil))` or switch to Postgres.
         | 
| 132 134 |  | 
| 133 135 | 
             
            ## Another nifty way to reduce extra queries
         | 
| @@ -184,6 +186,9 @@ This is a gem not a Rails pull request because the standard of code quality for | |
| 184 186 |  | 
| 185 187 | 
             
            ## Changelog
         | 
| 186 188 |  | 
| 189 | 
            +
            **1.3.0** - January 14, 2018
         | 
| 190 | 
            +
              - Ready for Rails 5.2! Updates provided by [@glebm](https://github.com/glebm).
         | 
| 191 | 
            +
             | 
| 187 192 | 
             
            **1.2.0** - June 26, 2016
         | 
| 188 193 | 
             
              - Ready for Rails 5.0! Updates provided by [@glebm](https://github.com/glebm).
         | 
| 189 194 |  | 
| @@ -209,9 +214,9 @@ This public domain dedication follows the the CC0 1.0 at https://creativecommons | |
| 209 214 | 
             
            2. Create your feature branch (`git checkout -b my-new-feature`)
         | 
| 210 215 | 
             
            3. Run the tests:
         | 
| 211 216 | 
             
              1. Install MySQL and PostgreSQL.
         | 
| 212 | 
            -
              2. You  | 
| 213 | 
            -
              3. Run `rake` to test with all supported Rails versions.
         | 
| 214 | 
            -
              4. Run `rake test_rails_4_2` or `rake  | 
| 217 | 
            +
              2. You need to be able to connect to a local MySQL and Postgres database as the default user, so the specs can create a `test_active_record_union` database. From a vanilla install of MariaDB from Homebrew, this just works. For Postgres installed by Homebrew, you may need to run `$ echo "create database my_computer_user_name;" | psql postgres` since the initial database created by Homebrew is named "postgres" but PG defaults to connecting to a database named after your username.
         | 
| 218 | 
            +
              3. Run `rake` to test with all supported Rails versions. All needed dependencies will be installed via Bundler (`gem install bundler` if you happen not to have Bundler yet).
         | 
| 219 | 
            +
              4. Run `rake test_rails_4_2` or `rake test_rails_5_2` etc. to test a specific Rails version.
         | 
| 215 220 | 
             
            4. There is also a `bin/console` command to load up a REPL for playing around
         | 
| 216 221 | 
             
            5. Commit your changes (`git commit -am 'Add some feature'`)
         | 
| 217 222 | 
             
            6. Push to the branch (`git push origin my-new-feature`)
         | 
| @@ -18,7 +18,7 @@ module ActiveRecord | |
| 18 18 | 
             
                  private
         | 
| 19 19 |  | 
| 20 20 | 
             
                  def set_operation(operation, relation_or_where_arg, *args)
         | 
| 21 | 
            -
                    other = if args. | 
| 21 | 
            +
                    other = if args.empty? && relation_or_where_arg.is_a?(Relation)
         | 
| 22 22 | 
             
                              relation_or_where_arg
         | 
| 23 23 | 
             
                            else
         | 
| 24 24 | 
             
                              @klass.where(relation_or_where_arg, *args)
         | 
| @@ -26,24 +26,56 @@ module ActiveRecord | |
| 26 26 |  | 
| 27 27 | 
             
                    verify_relations_for_set_operation!(operation, self, other)
         | 
| 28 28 |  | 
| 29 | 
            +
                    left = self.arel.ast
         | 
| 30 | 
            +
                    right = other.arel.ast
         | 
| 31 | 
            +
             | 
| 29 32 | 
             
                    # Postgres allows ORDER BY in the UNION subqueries if each subquery is surrounded by parenthesis
         | 
| 30 | 
            -
                    # but SQLite does not allow parens around the subqueries | 
| 31 | 
            -
                     | 
| 32 | 
            -
                      left | 
| 33 | 
            -
             | 
| 34 | 
            -
                      left, right = Arel::Nodes::Grouping.new(self.ast), Arel::Nodes::Grouping.new(other.ast)
         | 
| 33 | 
            +
                    # but SQLite does not allow parens around the subqueries
         | 
| 34 | 
            +
                    unless self.connection.visitor.is_a?(Arel::Visitors::SQLite)
         | 
| 35 | 
            +
                      left = Arel::Nodes::Grouping.new(left)
         | 
| 36 | 
            +
                      right = Arel::Nodes::Grouping.new(right)
         | 
| 35 37 | 
             
                    end
         | 
| 36 38 |  | 
| 37 39 | 
             
                    set  = SET_OPERATION_TO_AREL_CLASS[operation].new(left, right)
         | 
| 38 40 | 
             
                    from = Arel::Nodes::TableAlias.new(set, @klass.arel_table.name)
         | 
| 39 | 
            -
                     | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 41 | 
            +
                    build_union_relation(from, other)
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  if ActiveRecord.gem_version >= Gem::Version.new('5.2.0.beta2')
         | 
| 45 | 
            +
                    # Since Rails 5.2, binds are maintained only in the Arel AST.
         | 
| 46 | 
            +
                    def build_union_relation(arel_table_alias, _other)
         | 
| 47 | 
            +
                      @klass.unscoped.from(arel_table_alias)
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  elsif ActiveRecord::VERSION::MAJOR >= 5
         | 
| 50 | 
            +
                    # In Rails >= 5.0, < 5.2, binds are maintained only in ActiveRecord
         | 
| 51 | 
            +
                    # relations and clauses.
         | 
| 52 | 
            +
                    def build_union_relation(arel_table_alias, other)
         | 
| 53 | 
            +
                      relation = @klass.unscoped.spawn
         | 
| 54 | 
            +
                      relation.from_clause =
         | 
| 55 | 
            +
                        UnionFromClause.new(arel_table_alias, nil,
         | 
| 56 | 
            +
                                            self.bound_attributes + other.bound_attributes)
         | 
| 57 | 
            +
                      relation
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    class UnionFromClause < ActiveRecord::Relation::FromClause
         | 
| 61 | 
            +
                      def initialize(value, name, bound_attributes)
         | 
| 62 | 
            +
                        super(value, name)
         | 
| 63 | 
            +
                        @bound_attributes = bound_attributes
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      def binds
         | 
| 67 | 
            +
                        @bound_attributes
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  else
         | 
| 71 | 
            +
                    # In Rails 4.x, binds are maintained in both ActiveRecord relations and
         | 
| 72 | 
            +
                    # clauses and also in their Arel ASTs.
         | 
| 73 | 
            +
                    def build_union_relation(arel_table_alias, other)
         | 
| 74 | 
            +
                      relation = @klass.unscoped.from(arel_table_alias)
         | 
| 75 | 
            +
                      relation.bind_values = self.arel.bind_values + self.bind_values +
         | 
| 76 | 
            +
                                             other.arel.bind_values + other.bind_values
         | 
| 77 | 
            +
                      relation
         | 
| 45 78 | 
             
                    end
         | 
| 46 | 
            -
                    relation
         | 
| 47 79 | 
             
                  end
         | 
| 48 80 |  | 
| 49 81 | 
             
                  def verify_relations_for_set_operation!(operation, *relations)
         | 
| @@ -63,19 +95,6 @@ module ActiveRecord | |
| 63 95 | 
             
                      raise ArgumentError.new("Cannot #{operation} relation with eager load.")
         | 
| 64 96 | 
             
                    end
         | 
| 65 97 | 
             
                  end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                  if ActiveRecord::VERSION::MAJOR >= 5
         | 
| 68 | 
            -
                    class UnionFromClause < ActiveRecord::Relation::FromClause
         | 
| 69 | 
            -
                      def initialize(value, name, bound_attributes)
         | 
| 70 | 
            -
                        super(value, name)
         | 
| 71 | 
            -
                        @bound_attributes = bound_attributes
         | 
| 72 | 
            -
                      end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                      def binds
         | 
| 75 | 
            -
                        @bound_attributes
         | 
| 76 | 
            -
                      end
         | 
| 77 | 
            -
                    end
         | 
| 78 | 
            -
                  end
         | 
| 79 98 | 
             
                end
         | 
| 80 99 | 
             
              end
         | 
| 81 100 | 
             
            end
         | 
    
        data/rails_4_2.gemfile
    CHANGED
    
    | @@ -3,4 +3,9 @@ source 'https://rubygems.org' | |
| 3 3 | 
             
            # Specify your gem's dependencies in active_record_union.gemspec
         | 
| 4 4 | 
             
            gemspec
         | 
| 5 5 |  | 
| 6 | 
            -
            gem 'rails', '~> 4.2. | 
| 6 | 
            +
            gem 'rails', '~> 4.2.7'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # On Rails < 5.2, only pg < v1 is supported. See:
         | 
| 9 | 
            +
            # https://github.com/rails/rails/pull/31671
         | 
| 10 | 
            +
            # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
         | 
| 11 | 
            +
            gem 'pg', '~> 0.21'
         | 
    
        data/rails_5_0.gemfile
    CHANGED
    
    | @@ -3,4 +3,9 @@ source 'https://rubygems.org' | |
| 3 3 | 
             
            # Specify your gem's dependencies in active_record_union.gemspec
         | 
| 4 4 | 
             
            gemspec
         | 
| 5 5 |  | 
| 6 | 
            -
            gem 'rails',  | 
| 6 | 
            +
            gem 'rails', '~> 5.0.0'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # On Rails < 5.2, only pg < v1 is supported. See:
         | 
| 9 | 
            +
            # https://github.com/rails/rails/pull/31671
         | 
| 10 | 
            +
            # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
         | 
| 11 | 
            +
            gem 'pg', '~> 0.21'
         | 
    
        data/rails_5_1.gemfile
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            source 'https://rubygems.org'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Specify your gem's dependencies in active_record_union.gemspec
         | 
| 4 | 
            +
            gemspec
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            gem 'rails', '~> 5.1.0'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # On Rails < 5.2, only pg < v1 is supported. See:
         | 
| 9 | 
            +
            # https://github.com/rails/rails/pull/31671
         | 
| 10 | 
            +
            # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
         | 
| 11 | 
            +
            gem 'pg', '~> 0.21'
         | 
    
        data/rails_5_2.gemfile
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            source 'https://rubygems.org'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Specify your gem's dependencies in active_record_union.gemspec
         | 
| 4 | 
            +
            gemspec
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # pg v1.0+ compatibility, https://github.com/rails/rails/pull/31671:
         | 
| 7 | 
            +
            gem 'rails', '~> 5.2.0.beta2', git: 'https://github.com/rails/rails', ref: 'f1af27fd9d9101684b26d0dcf2028859d67bec1f'
         | 
    
        data/spec/union_spec.rb
    CHANGED
    
    | @@ -41,7 +41,11 @@ describe ActiveRecord::Relation do | |
| 41 41 | 
             
                end
         | 
| 42 42 |  | 
| 43 43 | 
             
                def bind_values_from_relation(relation)
         | 
| 44 | 
            -
                  if ActiveRecord | 
| 44 | 
            +
                  if ActiveRecord.gem_version >= Gem::Version.new('5.2.0.beta2')
         | 
| 45 | 
            +
                    relation.arel_table.class.engine.connection.visitor.accept(
         | 
| 46 | 
            +
                      relation.arel.ast, Arel::Collectors::Bind.new
         | 
| 47 | 
            +
                    ).value.map(&:value)
         | 
| 48 | 
            +
                  elsif ActiveRecord::VERSION::MAJOR >= 5
         | 
| 45 49 | 
             
                    relation.bound_attributes.map { |a| a.value_for_database }
         | 
| 46 50 | 
             
                  else
         | 
| 47 51 | 
             
                    (relation.arel.bind_values + relation.bind_values).map { |_column, value| value }
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: active_record_union
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Brian Hempel
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2018-01-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activerecord
         | 
| @@ -141,6 +141,8 @@ files: | |
| 141 141 | 
             
            - lib/active_record_union/version.rb
         | 
| 142 142 | 
             
            - rails_4_2.gemfile
         | 
| 143 143 | 
             
            - rails_5_0.gemfile
         | 
| 144 | 
            +
            - rails_5_1.gemfile
         | 
| 145 | 
            +
            - rails_5_2.gemfile
         | 
| 144 146 | 
             
            - spec/spec_helper.rb
         | 
| 145 147 | 
             
            - spec/support/databases.rb
         | 
| 146 148 | 
             
            - spec/support/models.rb
         | 
| @@ -165,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 165 167 | 
             
                  version: '0'
         | 
| 166 168 | 
             
            requirements: []
         | 
| 167 169 | 
             
            rubyforge_project: 
         | 
| 168 | 
            -
            rubygems_version: 2. | 
| 170 | 
            +
            rubygems_version: 2.6.8
         | 
| 169 171 | 
             
            signing_key: 
         | 
| 170 172 | 
             
            specification_version: 4
         | 
| 171 173 | 
             
            summary: UNIONs in ActiveRecord! Adds proper union and union_all methods to ActiveRecord::Relation.
         |