Rails: How to chain scope queries with OR instead of AND?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







127















I'm using Rails3, ActiveRecord



Just wondering how can I chain the scopes with OR statements rather than AND.



e.g.



Person.where(:name => "John").where(:lastname => "Smith")


That normally returns name = 'John' AND lastname = 'Smith', but I'd like:



name = 'John' OR lastname = 'Smith'










share|improve this question































    127















    I'm using Rails3, ActiveRecord



    Just wondering how can I chain the scopes with OR statements rather than AND.



    e.g.



    Person.where(:name => "John").where(:lastname => "Smith")


    That normally returns name = 'John' AND lastname = 'Smith', but I'd like:



    name = 'John' OR lastname = 'Smith'










    share|improve this question



























      127












      127








      127


      32






      I'm using Rails3, ActiveRecord



      Just wondering how can I chain the scopes with OR statements rather than AND.



      e.g.



      Person.where(:name => "John").where(:lastname => "Smith")


      That normally returns name = 'John' AND lastname = 'Smith', but I'd like:



      name = 'John' OR lastname = 'Smith'










      share|improve this question
















      I'm using Rails3, ActiveRecord



      Just wondering how can I chain the scopes with OR statements rather than AND.



      e.g.



      Person.where(:name => "John").where(:lastname => "Smith")


      That normally returns name = 'John' AND lastname = 'Smith', but I'd like:



      name = 'John' OR lastname = 'Smith'







      ruby-on-rails activerecord ruby-on-rails-3






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 10 '10 at 11:47









      Shadwell

      29.3k148089




      29.3k148089










      asked Sep 10 '10 at 11:41









      user410715user410715

      636264




      636264
























          19 Answers
          19






          active

          oldest

          votes


















          95














          You would do



          Person.where('name=? OR lastname=?', 'John', 'Smith')


          Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).






          share|improve this answer





















          • 21





            and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

            – CambridgeMike
            Nov 9 '11 at 3:55






          • 6





            This is still applicable in Rails 4? Nothing better came up in Rails 4?

            – Donato
            Apr 4 '15 at 21:18








          • 11





            No change in Rails 4, but Rails 5 will have .or built in.

            – lime
            Jun 11 '15 at 6:53






          • 3





            this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

            – miguelfg
            Oct 22 '15 at 11:47






          • 2





            With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

            – shyam
            Sep 28 '17 at 7:19



















          45














          Use ARel



          t = Person.arel_table

          results = Person.where(
          t[:name].eq("John").
          or(t[:lastname].eq("Smith"))
          )





          share|improve this answer



















          • 1





            Can anybody comment on whether this type of query breaks in Postgres?

            – Olivier Lacan
            Oct 28 '11 at 17:20






          • 2





            I'm using Postgres and this seemed to work fine.

            – MrTheWalrus
            Dec 7 '11 at 16:45











          • ARel is supposed to be DB-agnostic.

            – Simon Perepelitsa
            Jul 27 '12 at 16:17











          • While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

            – Olivier Lacan
            Aug 28 '14 at 3:45






          • 7





            @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

            – Gray
            Sep 30 '14 at 13:46





















          41














          According to this pull request, Rails 5 now supports the following syntax for chaining queries:



          Post.where(id: 1).or(Post.where(id: 2))


          There's also a backport of the functionality into Rails 4.2 via this gem.






          share|improve this answer































            38














            Update for Rails4



            requires no 3rd party gems



            a = Person.where(name: "John") # or any scope 
            b = Person.where(lastname: "Smith") # or any scope
            Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
            .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }


            Old answer



            requires no 3rd party gems



            Person.where(
            Person.where(:name => "John").where(:lastname => "Smith")
            .where_values.reduce(:or)
            )





            share|improve this answer





















            • 5





              this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

              – allenwlee
              Feb 12 '15 at 21:24






            • 6





              here's a decent article explaining it coderwall.com/p/dgv7ag/…

              – allenwlee
              Feb 12 '15 at 21:37






            • 4





              Used ...where_values.join(' OR ') in my case

              – Sash
              May 31 '15 at 17:56






            • 5





              How does this work in scopes?

              – baash05
              Jul 20 '15 at 2:20






            • 2





              You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

              – fatuhoku
              May 10 '16 at 12:44



















            36














            Just posting the Array syntax for same column OR queries to help peeps out.



            Person.where(name: ["John", "Steve"])





            share|improve this answer



















            • 2





              The question check John against name and Smith against lastname

              – steven_noble
              Aug 8 '15 at 1:21






            • 11





              @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

              – daino3
              Aug 10 '15 at 19:19



















            22














            In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.



            Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:



            Person.where(name: 'John').or.where(last_name: 'Smith').all


            Even more valuable is the ability to chain scopes with OR:



            scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
            scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }


            Then you can find all Persons with first or last name or whose parent with last name



            Person.first_or_last_name('John Smith').or.parent_last_name('Smith')


            Not the best example for the use of this, but just trying to fit it with the question.






            share|improve this answer



















            • 2





              Which version or Rails do you need for this?

              – Sash
              May 31 '15 at 11:44






            • 3





              The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

              – codenamev
              Jun 1 '15 at 12:31








            • 1





              Yep, it was merged and released with Rails 5.

              – amoebe
              Dec 2 '16 at 15:21



















            21














            You can also use MetaWhere gem to not mix up your code with SQL stuff:



            Person.where((:name => "John") | (:lastname => "Smith"))





            share|improve this answer
























            • good call on this one

              – Nick Vanderbilt
              Sep 13 '10 at 1:31






            • 3





              +1. The successor to MetaWhere is squeel by the same author.

              – Thilo
              Dec 22 '12 at 19:22



















            8














            This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:



            Person.where{(name == "John") | (lastname == "Smith")}


            You can mix and match AND/OR, among many other awesome things.






            share|improve this answer

































              8














              An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:



              Foo.where(foo: 'bar').or.where(bar: 'bar')


              As noted in this pull request https://github.com/rails/rails/pull/9052



              For now, simply sticking with the following works great:



              Foo.where('foo= ? OR bar= ?', 'bar', 'bar')





              share|improve this answer



















              • 5





                Not supported in Rails 4.2.5

                – fatuhoku
                Jul 29 '16 at 14:44











              • Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                – Ana María Martínez Gómez
                Nov 28 '18 at 13:42



















              7














              For me (Rails 4.2.5) it only works like this:



              { where("name = ? or name = ?", a, b) }





              share|improve this answer































                6














                Rails 4 + Scope + Arel



                class Creature < ActiveRecord::Base
                scope :is_good_pet, -> {
                where(
                arel_table[:is_cat].eq(true)
                .or(arel_table[:is_dog].eq(true))
                .or(arel_table[:eats_children].eq(false))
                )
                }
                end


                I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like



                SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))





                share|improve this answer































                  4














                  Rails 4



                  scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }





                  share|improve this answer































                    3














                    If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:



                    Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")


                    (source: ActiveRecord Query Union)



                    This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.



                    This will do the job, as long as you don't mind monkey patching rails.






                    share|improve this answer

































                      2














                      Also see these related questions: here, here and here



                      For rails 4, based on this article and this original answer



                      Person
                      .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
                      .where( # Begin a where clause
                      where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
                      .where_values # get an array of arel where clause conditions based on the chain thus far
                      .inject(:or) # inject the OR operator into the arels
                      # ^^ Inject may not work in Rails3. But this should work instead:
                      .joins(" OR ")
                      # ^^ Remember to only use .inject or .joins, not both
                      ) # Resurface the arels inside the overarching query


                      Note the article's caution at the end:




                      Rails 4.1+



                      Rails 4.1 treats default_scope just as a regular scope. The default
                      scope (if you have any) is included in the where_values result and
                      inject(:or) will add or statement between the default scope and your
                      wheres. That's bad.



                      To solve that, you just need to unscope the query.







                      share|improve this answer

































                        0














                        the squeel gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):



                        names = ["Kroger", "Walmart", "Target", "Aldi"]
                        matching_stores = Grocery.where{name.like_any(names)}





                        share|improve this answer































                          0














                          So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case



                          I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.



                          Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")


                          I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.



                          No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.






                          share|improve this answer































                            0














                            If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:



                            scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }


                            Or:



                            def self.john_or_smith
                            where(name: "John").or(where(lastname: "Smith"))
                            end





                            share|improve this answer
























                            • This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                              – RudyOnRails
                              Jan 2 at 23:46



















                            0














                            This is a very convenient way and it works fine in Rails 5:



                            Transaction
                            .where(transaction_type: ["Create", "Correspond"])
                            .or(
                            Transaction.where(
                            transaction_type: "Status",
                            field: "Status",
                            newvalue: ["resolved", "deleted"]
                            )
                            )
                            .or(
                            Transaction.where(transaction_type: "Set", field: "Queue")
                            )





                            share|improve this answer

































                              -2














                              names = ["tim", "tom", "bob", "alex"]
                              sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
                              @people = People.where(sql_string)





                              share|improve this answer



















                              • 4





                                this is vulnerable to sqlinjection...

                                – BvuRVKyUVlViVIc7
                                Jul 12 '13 at 18:57












                              Your Answer






                              StackExchange.ifUsing("editor", function () {
                              StackExchange.using("externalEditor", function () {
                              StackExchange.using("snippets", function () {
                              StackExchange.snippets.init();
                              });
                              });
                              }, "code-snippets");

                              StackExchange.ready(function() {
                              var channelOptions = {
                              tags: "".split(" "),
                              id: "1"
                              };
                              initTagRenderer("".split(" "), "".split(" "), channelOptions);

                              StackExchange.using("externalEditor", function() {
                              // Have to fire editor after snippets, if snippets enabled
                              if (StackExchange.settings.snippets.snippetsEnabled) {
                              StackExchange.using("snippets", function() {
                              createEditor();
                              });
                              }
                              else {
                              createEditor();
                              }
                              });

                              function createEditor() {
                              StackExchange.prepareEditor({
                              heartbeatType: 'answer',
                              autoActivateHeartbeat: false,
                              convertImagesToLinks: true,
                              noModals: true,
                              showLowRepImageUploadWarning: true,
                              reputationToPostImages: 10,
                              bindNavPrevention: true,
                              postfix: "",
                              imageUploader: {
                              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                              allowUrls: true
                              },
                              onDemand: true,
                              discardSelector: ".discard-answer"
                              ,immediatelyShowMarkdownHelp:true
                              });


                              }
                              });














                              draft saved

                              draft discarded


















                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3684311%2frails-how-to-chain-scope-queries-with-or-instead-of-and%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown

























                              19 Answers
                              19






                              active

                              oldest

                              votes








                              19 Answers
                              19






                              active

                              oldest

                              votes









                              active

                              oldest

                              votes






                              active

                              oldest

                              votes









                              95














                              You would do



                              Person.where('name=? OR lastname=?', 'John', 'Smith')


                              Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).






                              share|improve this answer





















                              • 21





                                and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                                – CambridgeMike
                                Nov 9 '11 at 3:55






                              • 6





                                This is still applicable in Rails 4? Nothing better came up in Rails 4?

                                – Donato
                                Apr 4 '15 at 21:18








                              • 11





                                No change in Rails 4, but Rails 5 will have .or built in.

                                – lime
                                Jun 11 '15 at 6:53






                              • 3





                                this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                                – miguelfg
                                Oct 22 '15 at 11:47






                              • 2





                                With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                                – shyam
                                Sep 28 '17 at 7:19
















                              95














                              You would do



                              Person.where('name=? OR lastname=?', 'John', 'Smith')


                              Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).






                              share|improve this answer





















                              • 21





                                and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                                – CambridgeMike
                                Nov 9 '11 at 3:55






                              • 6





                                This is still applicable in Rails 4? Nothing better came up in Rails 4?

                                – Donato
                                Apr 4 '15 at 21:18








                              • 11





                                No change in Rails 4, but Rails 5 will have .or built in.

                                – lime
                                Jun 11 '15 at 6:53






                              • 3





                                this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                                – miguelfg
                                Oct 22 '15 at 11:47






                              • 2





                                With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                                – shyam
                                Sep 28 '17 at 7:19














                              95












                              95








                              95







                              You would do



                              Person.where('name=? OR lastname=?', 'John', 'Smith')


                              Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).






                              share|improve this answer















                              You would do



                              Person.where('name=? OR lastname=?', 'John', 'Smith')


                              Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited May 9 '13 at 18:41









                              maerics

                              107k29205251




                              107k29205251










                              answered Sep 10 '10 at 12:38









                              PetrosPetros

                              7,48322630




                              7,48322630








                              • 21





                                and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                                – CambridgeMike
                                Nov 9 '11 at 3:55






                              • 6





                                This is still applicable in Rails 4? Nothing better came up in Rails 4?

                                – Donato
                                Apr 4 '15 at 21:18








                              • 11





                                No change in Rails 4, but Rails 5 will have .or built in.

                                – lime
                                Jun 11 '15 at 6:53






                              • 3





                                this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                                – miguelfg
                                Oct 22 '15 at 11:47






                              • 2





                                With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                                – shyam
                                Sep 28 '17 at 7:19














                              • 21





                                and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                                – CambridgeMike
                                Nov 9 '11 at 3:55






                              • 6





                                This is still applicable in Rails 4? Nothing better came up in Rails 4?

                                – Donato
                                Apr 4 '15 at 21:18








                              • 11





                                No change in Rails 4, but Rails 5 will have .or built in.

                                – lime
                                Jun 11 '15 at 6:53






                              • 3





                                this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                                – miguelfg
                                Oct 22 '15 at 11:47






                              • 2





                                With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                                – shyam
                                Sep 28 '17 at 7:19








                              21




                              21





                              and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                              – CambridgeMike
                              Nov 9 '11 at 3:55





                              and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')

                              – CambridgeMike
                              Nov 9 '11 at 3:55




                              6




                              6





                              This is still applicable in Rails 4? Nothing better came up in Rails 4?

                              – Donato
                              Apr 4 '15 at 21:18







                              This is still applicable in Rails 4? Nothing better came up in Rails 4?

                              – Donato
                              Apr 4 '15 at 21:18






                              11




                              11





                              No change in Rails 4, but Rails 5 will have .or built in.

                              – lime
                              Jun 11 '15 at 6:53





                              No change in Rails 4, but Rails 5 will have .or built in.

                              – lime
                              Jun 11 '15 at 6:53




                              3




                              3





                              this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                              – miguelfg
                              Oct 22 '15 at 11:47





                              this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.

                              – miguelfg
                              Oct 22 '15 at 11:47




                              2




                              2





                              With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                              – shyam
                              Sep 28 '17 at 7:19





                              With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))

                              – shyam
                              Sep 28 '17 at 7:19













                              45














                              Use ARel



                              t = Person.arel_table

                              results = Person.where(
                              t[:name].eq("John").
                              or(t[:lastname].eq("Smith"))
                              )





                              share|improve this answer



















                              • 1





                                Can anybody comment on whether this type of query breaks in Postgres?

                                – Olivier Lacan
                                Oct 28 '11 at 17:20






                              • 2





                                I'm using Postgres and this seemed to work fine.

                                – MrTheWalrus
                                Dec 7 '11 at 16:45











                              • ARel is supposed to be DB-agnostic.

                                – Simon Perepelitsa
                                Jul 27 '12 at 16:17











                              • While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                                – Olivier Lacan
                                Aug 28 '14 at 3:45






                              • 7





                                @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                                – Gray
                                Sep 30 '14 at 13:46


















                              45














                              Use ARel



                              t = Person.arel_table

                              results = Person.where(
                              t[:name].eq("John").
                              or(t[:lastname].eq("Smith"))
                              )





                              share|improve this answer



















                              • 1





                                Can anybody comment on whether this type of query breaks in Postgres?

                                – Olivier Lacan
                                Oct 28 '11 at 17:20






                              • 2





                                I'm using Postgres and this seemed to work fine.

                                – MrTheWalrus
                                Dec 7 '11 at 16:45











                              • ARel is supposed to be DB-agnostic.

                                – Simon Perepelitsa
                                Jul 27 '12 at 16:17











                              • While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                                – Olivier Lacan
                                Aug 28 '14 at 3:45






                              • 7





                                @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                                – Gray
                                Sep 30 '14 at 13:46
















                              45












                              45








                              45







                              Use ARel



                              t = Person.arel_table

                              results = Person.where(
                              t[:name].eq("John").
                              or(t[:lastname].eq("Smith"))
                              )





                              share|improve this answer













                              Use ARel



                              t = Person.arel_table

                              results = Person.where(
                              t[:name].eq("John").
                              or(t[:lastname].eq("Smith"))
                              )






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Sep 10 '10 at 12:57









                              Dan McNevinDan McNevin

                              20.9k43128




                              20.9k43128








                              • 1





                                Can anybody comment on whether this type of query breaks in Postgres?

                                – Olivier Lacan
                                Oct 28 '11 at 17:20






                              • 2





                                I'm using Postgres and this seemed to work fine.

                                – MrTheWalrus
                                Dec 7 '11 at 16:45











                              • ARel is supposed to be DB-agnostic.

                                – Simon Perepelitsa
                                Jul 27 '12 at 16:17











                              • While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                                – Olivier Lacan
                                Aug 28 '14 at 3:45






                              • 7





                                @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                                – Gray
                                Sep 30 '14 at 13:46
















                              • 1





                                Can anybody comment on whether this type of query breaks in Postgres?

                                – Olivier Lacan
                                Oct 28 '11 at 17:20






                              • 2





                                I'm using Postgres and this seemed to work fine.

                                – MrTheWalrus
                                Dec 7 '11 at 16:45











                              • ARel is supposed to be DB-agnostic.

                                – Simon Perepelitsa
                                Jul 27 '12 at 16:17











                              • While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                                – Olivier Lacan
                                Aug 28 '14 at 3:45






                              • 7





                                @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                                – Gray
                                Sep 30 '14 at 13:46










                              1




                              1





                              Can anybody comment on whether this type of query breaks in Postgres?

                              – Olivier Lacan
                              Oct 28 '11 at 17:20





                              Can anybody comment on whether this type of query breaks in Postgres?

                              – Olivier Lacan
                              Oct 28 '11 at 17:20




                              2




                              2





                              I'm using Postgres and this seemed to work fine.

                              – MrTheWalrus
                              Dec 7 '11 at 16:45





                              I'm using Postgres and this seemed to work fine.

                              – MrTheWalrus
                              Dec 7 '11 at 16:45













                              ARel is supposed to be DB-agnostic.

                              – Simon Perepelitsa
                              Jul 27 '12 at 16:17





                              ARel is supposed to be DB-agnostic.

                              – Simon Perepelitsa
                              Jul 27 '12 at 16:17













                              While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                              – Olivier Lacan
                              Aug 28 '14 at 3:45





                              While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.

                              – Olivier Lacan
                              Aug 28 '14 at 3:45




                              7




                              7





                              @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                              – Gray
                              Sep 30 '14 at 13:46







                              @OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.

                              – Gray
                              Sep 30 '14 at 13:46













                              41














                              According to this pull request, Rails 5 now supports the following syntax for chaining queries:



                              Post.where(id: 1).or(Post.where(id: 2))


                              There's also a backport of the functionality into Rails 4.2 via this gem.






                              share|improve this answer




























                                41














                                According to this pull request, Rails 5 now supports the following syntax for chaining queries:



                                Post.where(id: 1).or(Post.where(id: 2))


                                There's also a backport of the functionality into Rails 4.2 via this gem.






                                share|improve this answer


























                                  41












                                  41








                                  41







                                  According to this pull request, Rails 5 now supports the following syntax for chaining queries:



                                  Post.where(id: 1).or(Post.where(id: 2))


                                  There's also a backport of the functionality into Rails 4.2 via this gem.






                                  share|improve this answer













                                  According to this pull request, Rails 5 now supports the following syntax for chaining queries:



                                  Post.where(id: 1).or(Post.where(id: 2))


                                  There's also a backport of the functionality into Rails 4.2 via this gem.







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Mar 20 '17 at 2:05









                                  Ryan LeafRyan Leaf

                                  53157




                                  53157























                                      38














                                      Update for Rails4



                                      requires no 3rd party gems



                                      a = Person.where(name: "John") # or any scope 
                                      b = Person.where(lastname: "Smith") # or any scope
                                      Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
                                      .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }


                                      Old answer



                                      requires no 3rd party gems



                                      Person.where(
                                      Person.where(:name => "John").where(:lastname => "Smith")
                                      .where_values.reduce(:or)
                                      )





                                      share|improve this answer





















                                      • 5





                                        this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                        – allenwlee
                                        Feb 12 '15 at 21:24






                                      • 6





                                        here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                        – allenwlee
                                        Feb 12 '15 at 21:37






                                      • 4





                                        Used ...where_values.join(' OR ') in my case

                                        – Sash
                                        May 31 '15 at 17:56






                                      • 5





                                        How does this work in scopes?

                                        – baash05
                                        Jul 20 '15 at 2:20






                                      • 2





                                        You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                        – fatuhoku
                                        May 10 '16 at 12:44
















                                      38














                                      Update for Rails4



                                      requires no 3rd party gems



                                      a = Person.where(name: "John") # or any scope 
                                      b = Person.where(lastname: "Smith") # or any scope
                                      Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
                                      .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }


                                      Old answer



                                      requires no 3rd party gems



                                      Person.where(
                                      Person.where(:name => "John").where(:lastname => "Smith")
                                      .where_values.reduce(:or)
                                      )





                                      share|improve this answer





















                                      • 5





                                        this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                        – allenwlee
                                        Feb 12 '15 at 21:24






                                      • 6





                                        here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                        – allenwlee
                                        Feb 12 '15 at 21:37






                                      • 4





                                        Used ...where_values.join(' OR ') in my case

                                        – Sash
                                        May 31 '15 at 17:56






                                      • 5





                                        How does this work in scopes?

                                        – baash05
                                        Jul 20 '15 at 2:20






                                      • 2





                                        You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                        – fatuhoku
                                        May 10 '16 at 12:44














                                      38












                                      38








                                      38







                                      Update for Rails4



                                      requires no 3rd party gems



                                      a = Person.where(name: "John") # or any scope 
                                      b = Person.where(lastname: "Smith") # or any scope
                                      Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
                                      .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }


                                      Old answer



                                      requires no 3rd party gems



                                      Person.where(
                                      Person.where(:name => "John").where(:lastname => "Smith")
                                      .where_values.reduce(:or)
                                      )





                                      share|improve this answer















                                      Update for Rails4



                                      requires no 3rd party gems



                                      a = Person.where(name: "John") # or any scope 
                                      b = Person.where(lastname: "Smith") # or any scope
                                      Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
                                      .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }


                                      Old answer



                                      requires no 3rd party gems



                                      Person.where(
                                      Person.where(:name => "John").where(:lastname => "Smith")
                                      .where_values.reduce(:or)
                                      )






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Nov 26 '15 at 3:39

























                                      answered Nov 21 '14 at 12:01









                                      kissrobberkissrobber

                                      517412




                                      517412








                                      • 5





                                        this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                        – allenwlee
                                        Feb 12 '15 at 21:24






                                      • 6





                                        here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                        – allenwlee
                                        Feb 12 '15 at 21:37






                                      • 4





                                        Used ...where_values.join(' OR ') in my case

                                        – Sash
                                        May 31 '15 at 17:56






                                      • 5





                                        How does this work in scopes?

                                        – baash05
                                        Jul 20 '15 at 2:20






                                      • 2





                                        You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                        – fatuhoku
                                        May 10 '16 at 12:44














                                      • 5





                                        this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                        – allenwlee
                                        Feb 12 '15 at 21:24






                                      • 6





                                        here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                        – allenwlee
                                        Feb 12 '15 at 21:37






                                      • 4





                                        Used ...where_values.join(' OR ') in my case

                                        – Sash
                                        May 31 '15 at 17:56






                                      • 5





                                        How does this work in scopes?

                                        – baash05
                                        Jul 20 '15 at 2:20






                                      • 2





                                        You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                        – fatuhoku
                                        May 10 '16 at 12:44








                                      5




                                      5





                                      this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                      – allenwlee
                                      Feb 12 '15 at 21:24





                                      this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating or or other operators within a text block, neither of which is reflected in OP's code.

                                      – allenwlee
                                      Feb 12 '15 at 21:24




                                      6




                                      6





                                      here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                      – allenwlee
                                      Feb 12 '15 at 21:37





                                      here's a decent article explaining it coderwall.com/p/dgv7ag/…

                                      – allenwlee
                                      Feb 12 '15 at 21:37




                                      4




                                      4





                                      Used ...where_values.join(' OR ') in my case

                                      – Sash
                                      May 31 '15 at 17:56





                                      Used ...where_values.join(' OR ') in my case

                                      – Sash
                                      May 31 '15 at 17:56




                                      5




                                      5





                                      How does this work in scopes?

                                      – baash05
                                      Jul 20 '15 at 2:20





                                      How does this work in scopes?

                                      – baash05
                                      Jul 20 '15 at 2:20




                                      2




                                      2





                                      You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                      – fatuhoku
                                      May 10 '16 at 12:44





                                      You can omit the .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) } part if your scopes don't have any variables that need binding.

                                      – fatuhoku
                                      May 10 '16 at 12:44











                                      36














                                      Just posting the Array syntax for same column OR queries to help peeps out.



                                      Person.where(name: ["John", "Steve"])





                                      share|improve this answer



















                                      • 2





                                        The question check John against name and Smith against lastname

                                        – steven_noble
                                        Aug 8 '15 at 1:21






                                      • 11





                                        @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                        – daino3
                                        Aug 10 '15 at 19:19
















                                      36














                                      Just posting the Array syntax for same column OR queries to help peeps out.



                                      Person.where(name: ["John", "Steve"])





                                      share|improve this answer



















                                      • 2





                                        The question check John against name and Smith against lastname

                                        – steven_noble
                                        Aug 8 '15 at 1:21






                                      • 11





                                        @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                        – daino3
                                        Aug 10 '15 at 19:19














                                      36












                                      36








                                      36







                                      Just posting the Array syntax for same column OR queries to help peeps out.



                                      Person.where(name: ["John", "Steve"])





                                      share|improve this answer













                                      Just posting the Array syntax for same column OR queries to help peeps out.



                                      Person.where(name: ["John", "Steve"])






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jul 24 '15 at 21:30









                                      daino3daino3

                                      1,9611628




                                      1,9611628








                                      • 2





                                        The question check John against name and Smith against lastname

                                        – steven_noble
                                        Aug 8 '15 at 1:21






                                      • 11





                                        @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                        – daino3
                                        Aug 10 '15 at 19:19














                                      • 2





                                        The question check John against name and Smith against lastname

                                        – steven_noble
                                        Aug 8 '15 at 1:21






                                      • 11





                                        @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                        – daino3
                                        Aug 10 '15 at 19:19








                                      2




                                      2





                                      The question check John against name and Smith against lastname

                                      – steven_noble
                                      Aug 8 '15 at 1:21





                                      The question check John against name and Smith against lastname

                                      – steven_noble
                                      Aug 8 '15 at 1:21




                                      11




                                      11





                                      @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                      – daino3
                                      Aug 10 '15 at 19:19





                                      @steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.

                                      – daino3
                                      Aug 10 '15 at 19:19











                                      22














                                      In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.



                                      Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:



                                      Person.where(name: 'John').or.where(last_name: 'Smith').all


                                      Even more valuable is the ability to chain scopes with OR:



                                      scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
                                      scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }


                                      Then you can find all Persons with first or last name or whose parent with last name



                                      Person.first_or_last_name('John Smith').or.parent_last_name('Smith')


                                      Not the best example for the use of this, but just trying to fit it with the question.






                                      share|improve this answer



















                                      • 2





                                        Which version or Rails do you need for this?

                                        – Sash
                                        May 31 '15 at 11:44






                                      • 3





                                        The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                        – codenamev
                                        Jun 1 '15 at 12:31








                                      • 1





                                        Yep, it was merged and released with Rails 5.

                                        – amoebe
                                        Dec 2 '16 at 15:21
















                                      22














                                      In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.



                                      Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:



                                      Person.where(name: 'John').or.where(last_name: 'Smith').all


                                      Even more valuable is the ability to chain scopes with OR:



                                      scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
                                      scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }


                                      Then you can find all Persons with first or last name or whose parent with last name



                                      Person.first_or_last_name('John Smith').or.parent_last_name('Smith')


                                      Not the best example for the use of this, but just trying to fit it with the question.






                                      share|improve this answer



















                                      • 2





                                        Which version or Rails do you need for this?

                                        – Sash
                                        May 31 '15 at 11:44






                                      • 3





                                        The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                        – codenamev
                                        Jun 1 '15 at 12:31








                                      • 1





                                        Yep, it was merged and released with Rails 5.

                                        – amoebe
                                        Dec 2 '16 at 15:21














                                      22












                                      22








                                      22







                                      In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.



                                      Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:



                                      Person.where(name: 'John').or.where(last_name: 'Smith').all


                                      Even more valuable is the ability to chain scopes with OR:



                                      scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
                                      scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }


                                      Then you can find all Persons with first or last name or whose parent with last name



                                      Person.first_or_last_name('John Smith').or.parent_last_name('Smith')


                                      Not the best example for the use of this, but just trying to fit it with the question.






                                      share|improve this answer













                                      In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.



                                      Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:



                                      Person.where(name: 'John').or.where(last_name: 'Smith').all


                                      Even more valuable is the ability to chain scopes with OR:



                                      scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
                                      scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }


                                      Then you can find all Persons with first or last name or whose parent with last name



                                      Person.first_or_last_name('John Smith').or.parent_last_name('Smith')


                                      Not the best example for the use of this, but just trying to fit it with the question.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Aug 12 '13 at 16:47









                                      codenamevcodenamev

                                      1,5431220




                                      1,5431220








                                      • 2





                                        Which version or Rails do you need for this?

                                        – Sash
                                        May 31 '15 at 11:44






                                      • 3





                                        The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                        – codenamev
                                        Jun 1 '15 at 12:31








                                      • 1





                                        Yep, it was merged and released with Rails 5.

                                        – amoebe
                                        Dec 2 '16 at 15:21














                                      • 2





                                        Which version or Rails do you need for this?

                                        – Sash
                                        May 31 '15 at 11:44






                                      • 3





                                        The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                        – codenamev
                                        Jun 1 '15 at 12:31








                                      • 1





                                        Yep, it was merged and released with Rails 5.

                                        – amoebe
                                        Dec 2 '16 at 15:21








                                      2




                                      2





                                      Which version or Rails do you need for this?

                                      – Sash
                                      May 31 '15 at 11:44





                                      Which version or Rails do you need for this?

                                      – Sash
                                      May 31 '15 at 11:44




                                      3




                                      3





                                      The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                      – codenamev
                                      Jun 1 '15 at 12:31







                                      The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the .or chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.

                                      – codenamev
                                      Jun 1 '15 at 12:31






                                      1




                                      1





                                      Yep, it was merged and released with Rails 5.

                                      – amoebe
                                      Dec 2 '16 at 15:21





                                      Yep, it was merged and released with Rails 5.

                                      – amoebe
                                      Dec 2 '16 at 15:21











                                      21














                                      You can also use MetaWhere gem to not mix up your code with SQL stuff:



                                      Person.where((:name => "John") | (:lastname => "Smith"))





                                      share|improve this answer
























                                      • good call on this one

                                        – Nick Vanderbilt
                                        Sep 13 '10 at 1:31






                                      • 3





                                        +1. The successor to MetaWhere is squeel by the same author.

                                        – Thilo
                                        Dec 22 '12 at 19:22
















                                      21














                                      You can also use MetaWhere gem to not mix up your code with SQL stuff:



                                      Person.where((:name => "John") | (:lastname => "Smith"))





                                      share|improve this answer
























                                      • good call on this one

                                        – Nick Vanderbilt
                                        Sep 13 '10 at 1:31






                                      • 3





                                        +1. The successor to MetaWhere is squeel by the same author.

                                        – Thilo
                                        Dec 22 '12 at 19:22














                                      21












                                      21








                                      21







                                      You can also use MetaWhere gem to not mix up your code with SQL stuff:



                                      Person.where((:name => "John") | (:lastname => "Smith"))





                                      share|improve this answer













                                      You can also use MetaWhere gem to not mix up your code with SQL stuff:



                                      Person.where((:name => "John") | (:lastname => "Smith"))






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Sep 10 '10 at 15:14









                                      Simon PerepelitsaSimon Perepelitsa

                                      15.8k85170




                                      15.8k85170













                                      • good call on this one

                                        – Nick Vanderbilt
                                        Sep 13 '10 at 1:31






                                      • 3





                                        +1. The successor to MetaWhere is squeel by the same author.

                                        – Thilo
                                        Dec 22 '12 at 19:22



















                                      • good call on this one

                                        – Nick Vanderbilt
                                        Sep 13 '10 at 1:31






                                      • 3





                                        +1. The successor to MetaWhere is squeel by the same author.

                                        – Thilo
                                        Dec 22 '12 at 19:22

















                                      good call on this one

                                      – Nick Vanderbilt
                                      Sep 13 '10 at 1:31





                                      good call on this one

                                      – Nick Vanderbilt
                                      Sep 13 '10 at 1:31




                                      3




                                      3





                                      +1. The successor to MetaWhere is squeel by the same author.

                                      – Thilo
                                      Dec 22 '12 at 19:22





                                      +1. The successor to MetaWhere is squeel by the same author.

                                      – Thilo
                                      Dec 22 '12 at 19:22











                                      8














                                      This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:



                                      Person.where{(name == "John") | (lastname == "Smith")}


                                      You can mix and match AND/OR, among many other awesome things.






                                      share|improve this answer






























                                        8














                                        This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:



                                        Person.where{(name == "John") | (lastname == "Smith")}


                                        You can mix and match AND/OR, among many other awesome things.






                                        share|improve this answer




























                                          8












                                          8








                                          8







                                          This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:



                                          Person.where{(name == "John") | (lastname == "Smith")}


                                          You can mix and match AND/OR, among many other awesome things.






                                          share|improve this answer















                                          This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:



                                          Person.where{(name == "John") | (lastname == "Smith")}


                                          You can mix and match AND/OR, among many other awesome things.







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Feb 16 '13 at 22:42

























                                          answered Jan 12 '12 at 1:33









                                          dhulihandhulihan

                                          7,01483243




                                          7,01483243























                                              8














                                              An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:



                                              Foo.where(foo: 'bar').or.where(bar: 'bar')


                                              As noted in this pull request https://github.com/rails/rails/pull/9052



                                              For now, simply sticking with the following works great:



                                              Foo.where('foo= ? OR bar= ?', 'bar', 'bar')





                                              share|improve this answer



















                                              • 5





                                                Not supported in Rails 4.2.5

                                                – fatuhoku
                                                Jul 29 '16 at 14:44











                                              • Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                                – Ana María Martínez Gómez
                                                Nov 28 '18 at 13:42
















                                              8














                                              An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:



                                              Foo.where(foo: 'bar').or.where(bar: 'bar')


                                              As noted in this pull request https://github.com/rails/rails/pull/9052



                                              For now, simply sticking with the following works great:



                                              Foo.where('foo= ? OR bar= ?', 'bar', 'bar')





                                              share|improve this answer



















                                              • 5





                                                Not supported in Rails 4.2.5

                                                – fatuhoku
                                                Jul 29 '16 at 14:44











                                              • Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                                – Ana María Martínez Gómez
                                                Nov 28 '18 at 13:42














                                              8












                                              8








                                              8







                                              An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:



                                              Foo.where(foo: 'bar').or.where(bar: 'bar')


                                              As noted in this pull request https://github.com/rails/rails/pull/9052



                                              For now, simply sticking with the following works great:



                                              Foo.where('foo= ? OR bar= ?', 'bar', 'bar')





                                              share|improve this answer













                                              An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:



                                              Foo.where(foo: 'bar').or.where(bar: 'bar')


                                              As noted in this pull request https://github.com/rails/rails/pull/9052



                                              For now, simply sticking with the following works great:



                                              Foo.where('foo= ? OR bar= ?', 'bar', 'bar')






                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Dec 18 '14 at 10:55









                                              Christian FazziniChristian Fazzini

                                              12.3k1991196




                                              12.3k1991196








                                              • 5





                                                Not supported in Rails 4.2.5

                                                – fatuhoku
                                                Jul 29 '16 at 14:44











                                              • Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                                – Ana María Martínez Gómez
                                                Nov 28 '18 at 13:42














                                              • 5





                                                Not supported in Rails 4.2.5

                                                – fatuhoku
                                                Jul 29 '16 at 14:44











                                              • Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                                – Ana María Martínez Gómez
                                                Nov 28 '18 at 13:42








                                              5




                                              5





                                              Not supported in Rails 4.2.5

                                              – fatuhoku
                                              Jul 29 '16 at 14:44





                                              Not supported in Rails 4.2.5

                                              – fatuhoku
                                              Jul 29 '16 at 14:44













                                              Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                              – Ana María Martínez Gómez
                                              Nov 28 '18 at 13:42





                                              Foo.where(foo: 'bar1').or.where(bar: 'bar2') does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))

                                              – Ana María Martínez Gómez
                                              Nov 28 '18 at 13:42











                                              7














                                              For me (Rails 4.2.5) it only works like this:



                                              { where("name = ? or name = ?", a, b) }





                                              share|improve this answer




























                                                7














                                                For me (Rails 4.2.5) it only works like this:



                                                { where("name = ? or name = ?", a, b) }





                                                share|improve this answer


























                                                  7












                                                  7








                                                  7







                                                  For me (Rails 4.2.5) it only works like this:



                                                  { where("name = ? or name = ?", a, b) }





                                                  share|improve this answer













                                                  For me (Rails 4.2.5) it only works like this:



                                                  { where("name = ? or name = ?", a, b) }






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Jun 29 '16 at 20:29









                                                  ZsoltZsolt

                                                  168112




                                                  168112























                                                      6














                                                      Rails 4 + Scope + Arel



                                                      class Creature < ActiveRecord::Base
                                                      scope :is_good_pet, -> {
                                                      where(
                                                      arel_table[:is_cat].eq(true)
                                                      .or(arel_table[:is_dog].eq(true))
                                                      .or(arel_table[:eats_children].eq(false))
                                                      )
                                                      }
                                                      end


                                                      I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like



                                                      SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))





                                                      share|improve this answer




























                                                        6














                                                        Rails 4 + Scope + Arel



                                                        class Creature < ActiveRecord::Base
                                                        scope :is_good_pet, -> {
                                                        where(
                                                        arel_table[:is_cat].eq(true)
                                                        .or(arel_table[:is_dog].eq(true))
                                                        .or(arel_table[:eats_children].eq(false))
                                                        )
                                                        }
                                                        end


                                                        I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like



                                                        SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))





                                                        share|improve this answer


























                                                          6












                                                          6








                                                          6







                                                          Rails 4 + Scope + Arel



                                                          class Creature < ActiveRecord::Base
                                                          scope :is_good_pet, -> {
                                                          where(
                                                          arel_table[:is_cat].eq(true)
                                                          .or(arel_table[:is_dog].eq(true))
                                                          .or(arel_table[:eats_children].eq(false))
                                                          )
                                                          }
                                                          end


                                                          I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like



                                                          SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))





                                                          share|improve this answer













                                                          Rails 4 + Scope + Arel



                                                          class Creature < ActiveRecord::Base
                                                          scope :is_good_pet, -> {
                                                          where(
                                                          arel_table[:is_cat].eq(true)
                                                          .or(arel_table[:is_dog].eq(true))
                                                          .or(arel_table[:eats_children].eq(false))
                                                          )
                                                          }
                                                          end


                                                          I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like



                                                          SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))






                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered Jul 15 '14 at 21:12









                                                          genkilabsgenkilabs

                                                          2,2012032




                                                          2,2012032























                                                              4














                                                              Rails 4



                                                              scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }





                                                              share|improve this answer




























                                                                4














                                                                Rails 4



                                                                scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }





                                                                share|improve this answer


























                                                                  4












                                                                  4








                                                                  4







                                                                  Rails 4



                                                                  scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }





                                                                  share|improve this answer













                                                                  Rails 4



                                                                  scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }






                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered May 19 '14 at 11:24









                                                                  AbsAbs

                                                                  3,07212226




                                                                  3,07212226























                                                                      3














                                                                      If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:



                                                                      Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")


                                                                      (source: ActiveRecord Query Union)



                                                                      This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.



                                                                      This will do the job, as long as you don't mind monkey patching rails.






                                                                      share|improve this answer






























                                                                        3














                                                                        If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:



                                                                        Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")


                                                                        (source: ActiveRecord Query Union)



                                                                        This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.



                                                                        This will do the job, as long as you don't mind monkey patching rails.






                                                                        share|improve this answer




























                                                                          3












                                                                          3








                                                                          3







                                                                          If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:



                                                                          Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")


                                                                          (source: ActiveRecord Query Union)



                                                                          This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.



                                                                          This will do the job, as long as you don't mind monkey patching rails.






                                                                          share|improve this answer















                                                                          If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:



                                                                          Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")


                                                                          (source: ActiveRecord Query Union)



                                                                          This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.



                                                                          This will do the job, as long as you don't mind monkey patching rails.







                                                                          share|improve this answer














                                                                          share|improve this answer



                                                                          share|improve this answer








                                                                          edited May 23 '17 at 12:18









                                                                          Community

                                                                          11




                                                                          11










                                                                          answered Nov 29 '13 at 2:10









                                                                          Jake ChristensenJake Christensen

                                                                          397312




                                                                          397312























                                                                              2














                                                                              Also see these related questions: here, here and here



                                                                              For rails 4, based on this article and this original answer



                                                                              Person
                                                                              .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
                                                                              .where( # Begin a where clause
                                                                              where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
                                                                              .where_values # get an array of arel where clause conditions based on the chain thus far
                                                                              .inject(:or) # inject the OR operator into the arels
                                                                              # ^^ Inject may not work in Rails3. But this should work instead:
                                                                              .joins(" OR ")
                                                                              # ^^ Remember to only use .inject or .joins, not both
                                                                              ) # Resurface the arels inside the overarching query


                                                                              Note the article's caution at the end:




                                                                              Rails 4.1+



                                                                              Rails 4.1 treats default_scope just as a regular scope. The default
                                                                              scope (if you have any) is included in the where_values result and
                                                                              inject(:or) will add or statement between the default scope and your
                                                                              wheres. That's bad.



                                                                              To solve that, you just need to unscope the query.







                                                                              share|improve this answer






























                                                                                2














                                                                                Also see these related questions: here, here and here



                                                                                For rails 4, based on this article and this original answer



                                                                                Person
                                                                                .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
                                                                                .where( # Begin a where clause
                                                                                where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
                                                                                .where_values # get an array of arel where clause conditions based on the chain thus far
                                                                                .inject(:or) # inject the OR operator into the arels
                                                                                # ^^ Inject may not work in Rails3. But this should work instead:
                                                                                .joins(" OR ")
                                                                                # ^^ Remember to only use .inject or .joins, not both
                                                                                ) # Resurface the arels inside the overarching query


                                                                                Note the article's caution at the end:




                                                                                Rails 4.1+



                                                                                Rails 4.1 treats default_scope just as a regular scope. The default
                                                                                scope (if you have any) is included in the where_values result and
                                                                                inject(:or) will add or statement between the default scope and your
                                                                                wheres. That's bad.



                                                                                To solve that, you just need to unscope the query.







                                                                                share|improve this answer




























                                                                                  2












                                                                                  2








                                                                                  2







                                                                                  Also see these related questions: here, here and here



                                                                                  For rails 4, based on this article and this original answer



                                                                                  Person
                                                                                  .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
                                                                                  .where( # Begin a where clause
                                                                                  where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
                                                                                  .where_values # get an array of arel where clause conditions based on the chain thus far
                                                                                  .inject(:or) # inject the OR operator into the arels
                                                                                  # ^^ Inject may not work in Rails3. But this should work instead:
                                                                                  .joins(" OR ")
                                                                                  # ^^ Remember to only use .inject or .joins, not both
                                                                                  ) # Resurface the arels inside the overarching query


                                                                                  Note the article's caution at the end:




                                                                                  Rails 4.1+



                                                                                  Rails 4.1 treats default_scope just as a regular scope. The default
                                                                                  scope (if you have any) is included in the where_values result and
                                                                                  inject(:or) will add or statement between the default scope and your
                                                                                  wheres. That's bad.



                                                                                  To solve that, you just need to unscope the query.







                                                                                  share|improve this answer















                                                                                  Also see these related questions: here, here and here



                                                                                  For rails 4, based on this article and this original answer



                                                                                  Person
                                                                                  .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
                                                                                  .where( # Begin a where clause
                                                                                  where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
                                                                                  .where_values # get an array of arel where clause conditions based on the chain thus far
                                                                                  .inject(:or) # inject the OR operator into the arels
                                                                                  # ^^ Inject may not work in Rails3. But this should work instead:
                                                                                  .joins(" OR ")
                                                                                  # ^^ Remember to only use .inject or .joins, not both
                                                                                  ) # Resurface the arels inside the overarching query


                                                                                  Note the article's caution at the end:




                                                                                  Rails 4.1+



                                                                                  Rails 4.1 treats default_scope just as a regular scope. The default
                                                                                  scope (if you have any) is included in the where_values result and
                                                                                  inject(:or) will add or statement between the default scope and your
                                                                                  wheres. That's bad.



                                                                                  To solve that, you just need to unscope the query.








                                                                                  share|improve this answer














                                                                                  share|improve this answer



                                                                                  share|improve this answer








                                                                                  edited May 23 '17 at 12:34









                                                                                  Community

                                                                                  11




                                                                                  11










                                                                                  answered Oct 26 '16 at 18:18









                                                                                  HeyZikoHeyZiko

                                                                                  1,0011016




                                                                                  1,0011016























                                                                                      0














                                                                                      the squeel gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):



                                                                                      names = ["Kroger", "Walmart", "Target", "Aldi"]
                                                                                      matching_stores = Grocery.where{name.like_any(names)}





                                                                                      share|improve this answer




























                                                                                        0














                                                                                        the squeel gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):



                                                                                        names = ["Kroger", "Walmart", "Target", "Aldi"]
                                                                                        matching_stores = Grocery.where{name.like_any(names)}





                                                                                        share|improve this answer


























                                                                                          0












                                                                                          0








                                                                                          0







                                                                                          the squeel gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):



                                                                                          names = ["Kroger", "Walmart", "Target", "Aldi"]
                                                                                          matching_stores = Grocery.where{name.like_any(names)}





                                                                                          share|improve this answer













                                                                                          the squeel gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):



                                                                                          names = ["Kroger", "Walmart", "Target", "Aldi"]
                                                                                          matching_stores = Grocery.where{name.like_any(names)}






                                                                                          share|improve this answer












                                                                                          share|improve this answer



                                                                                          share|improve this answer










                                                                                          answered Oct 3 '13 at 21:34









                                                                                          boulder_rubyboulder_ruby

                                                                                          27.3k65975




                                                                                          27.3k65975























                                                                                              0














                                                                                              So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case



                                                                                              I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.



                                                                                              Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")


                                                                                              I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.



                                                                                              No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.






                                                                                              share|improve this answer




























                                                                                                0














                                                                                                So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case



                                                                                                I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.



                                                                                                Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")


                                                                                                I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.



                                                                                                No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.






                                                                                                share|improve this answer


























                                                                                                  0












                                                                                                  0








                                                                                                  0







                                                                                                  So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case



                                                                                                  I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.



                                                                                                  Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")


                                                                                                  I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.



                                                                                                  No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.






                                                                                                  share|improve this answer













                                                                                                  So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case



                                                                                                  I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.



                                                                                                  Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")


                                                                                                  I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.



                                                                                                  No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.







                                                                                                  share|improve this answer












                                                                                                  share|improve this answer



                                                                                                  share|improve this answer










                                                                                                  answered Jul 10 '17 at 16:43









                                                                                                  John SmallJohn Small

                                                                                                  4761819




                                                                                                  4761819























                                                                                                      0














                                                                                                      If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:



                                                                                                      scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }


                                                                                                      Or:



                                                                                                      def self.john_or_smith
                                                                                                      where(name: "John").or(where(lastname: "Smith"))
                                                                                                      end





                                                                                                      share|improve this answer
























                                                                                                      • This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                        – RudyOnRails
                                                                                                        Jan 2 at 23:46
















                                                                                                      0














                                                                                                      If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:



                                                                                                      scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }


                                                                                                      Or:



                                                                                                      def self.john_or_smith
                                                                                                      where(name: "John").or(where(lastname: "Smith"))
                                                                                                      end





                                                                                                      share|improve this answer
























                                                                                                      • This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                        – RudyOnRails
                                                                                                        Jan 2 at 23:46














                                                                                                      0












                                                                                                      0








                                                                                                      0







                                                                                                      If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:



                                                                                                      scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }


                                                                                                      Or:



                                                                                                      def self.john_or_smith
                                                                                                      where(name: "John").or(where(lastname: "Smith"))
                                                                                                      end





                                                                                                      share|improve this answer













                                                                                                      If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:



                                                                                                      scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }


                                                                                                      Or:



                                                                                                      def self.john_or_smith
                                                                                                      where(name: "John").or(where(lastname: "Smith"))
                                                                                                      end






                                                                                                      share|improve this answer












                                                                                                      share|improve this answer



                                                                                                      share|improve this answer










                                                                                                      answered Nov 16 '18 at 12:00









                                                                                                      thisismydesignthisismydesign

                                                                                                      1,0281019




                                                                                                      1,0281019













                                                                                                      • This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                        – RudyOnRails
                                                                                                        Jan 2 at 23:46



















                                                                                                      • This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                        – RudyOnRails
                                                                                                        Jan 2 at 23:46

















                                                                                                      This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                      – RudyOnRails
                                                                                                      Jan 2 at 23:46





                                                                                                      This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.

                                                                                                      – RudyOnRails
                                                                                                      Jan 2 at 23:46











                                                                                                      0














                                                                                                      This is a very convenient way and it works fine in Rails 5:



                                                                                                      Transaction
                                                                                                      .where(transaction_type: ["Create", "Correspond"])
                                                                                                      .or(
                                                                                                      Transaction.where(
                                                                                                      transaction_type: "Status",
                                                                                                      field: "Status",
                                                                                                      newvalue: ["resolved", "deleted"]
                                                                                                      )
                                                                                                      )
                                                                                                      .or(
                                                                                                      Transaction.where(transaction_type: "Set", field: "Queue")
                                                                                                      )





                                                                                                      share|improve this answer






























                                                                                                        0














                                                                                                        This is a very convenient way and it works fine in Rails 5:



                                                                                                        Transaction
                                                                                                        .where(transaction_type: ["Create", "Correspond"])
                                                                                                        .or(
                                                                                                        Transaction.where(
                                                                                                        transaction_type: "Status",
                                                                                                        field: "Status",
                                                                                                        newvalue: ["resolved", "deleted"]
                                                                                                        )
                                                                                                        )
                                                                                                        .or(
                                                                                                        Transaction.where(transaction_type: "Set", field: "Queue")
                                                                                                        )





                                                                                                        share|improve this answer




























                                                                                                          0












                                                                                                          0








                                                                                                          0







                                                                                                          This is a very convenient way and it works fine in Rails 5:



                                                                                                          Transaction
                                                                                                          .where(transaction_type: ["Create", "Correspond"])
                                                                                                          .or(
                                                                                                          Transaction.where(
                                                                                                          transaction_type: "Status",
                                                                                                          field: "Status",
                                                                                                          newvalue: ["resolved", "deleted"]
                                                                                                          )
                                                                                                          )
                                                                                                          .or(
                                                                                                          Transaction.where(transaction_type: "Set", field: "Queue")
                                                                                                          )





                                                                                                          share|improve this answer















                                                                                                          This is a very convenient way and it works fine in Rails 5:



                                                                                                          Transaction
                                                                                                          .where(transaction_type: ["Create", "Correspond"])
                                                                                                          .or(
                                                                                                          Transaction.where(
                                                                                                          transaction_type: "Status",
                                                                                                          field: "Status",
                                                                                                          newvalue: ["resolved", "deleted"]
                                                                                                          )
                                                                                                          )
                                                                                                          .or(
                                                                                                          Transaction.where(transaction_type: "Set", field: "Queue")
                                                                                                          )






                                                                                                          share|improve this answer














                                                                                                          share|improve this answer



                                                                                                          share|improve this answer








                                                                                                          edited Mar 20 at 11:13









                                                                                                          Maksim Kalmykov

                                                                                                          93431220




                                                                                                          93431220










                                                                                                          answered Mar 6 at 10:16









                                                                                                          Jigar BhattJigar Bhatt

                                                                                                          1,5411626




                                                                                                          1,5411626























                                                                                                              -2














                                                                                                              names = ["tim", "tom", "bob", "alex"]
                                                                                                              sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
                                                                                                              @people = People.where(sql_string)





                                                                                                              share|improve this answer



















                                                                                                              • 4





                                                                                                                this is vulnerable to sqlinjection...

                                                                                                                – BvuRVKyUVlViVIc7
                                                                                                                Jul 12 '13 at 18:57
















                                                                                                              -2














                                                                                                              names = ["tim", "tom", "bob", "alex"]
                                                                                                              sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
                                                                                                              @people = People.where(sql_string)





                                                                                                              share|improve this answer



















                                                                                                              • 4





                                                                                                                this is vulnerable to sqlinjection...

                                                                                                                – BvuRVKyUVlViVIc7
                                                                                                                Jul 12 '13 at 18:57














                                                                                                              -2












                                                                                                              -2








                                                                                                              -2







                                                                                                              names = ["tim", "tom", "bob", "alex"]
                                                                                                              sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
                                                                                                              @people = People.where(sql_string)





                                                                                                              share|improve this answer













                                                                                                              names = ["tim", "tom", "bob", "alex"]
                                                                                                              sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
                                                                                                              @people = People.where(sql_string)






                                                                                                              share|improve this answer












                                                                                                              share|improve this answer



                                                                                                              share|improve this answer










                                                                                                              answered Mar 11 '13 at 6:45









                                                                                                              coloradobluecoloradoblue

                                                                                                              571610




                                                                                                              571610








                                                                                                              • 4





                                                                                                                this is vulnerable to sqlinjection...

                                                                                                                – BvuRVKyUVlViVIc7
                                                                                                                Jul 12 '13 at 18:57














                                                                                                              • 4





                                                                                                                this is vulnerable to sqlinjection...

                                                                                                                – BvuRVKyUVlViVIc7
                                                                                                                Jul 12 '13 at 18:57








                                                                                                              4




                                                                                                              4





                                                                                                              this is vulnerable to sqlinjection...

                                                                                                              – BvuRVKyUVlViVIc7
                                                                                                              Jul 12 '13 at 18:57





                                                                                                              this is vulnerable to sqlinjection...

                                                                                                              – BvuRVKyUVlViVIc7
                                                                                                              Jul 12 '13 at 18:57


















                                                                                                              draft saved

                                                                                                              draft discarded




















































                                                                                                              Thanks for contributing an answer to Stack Overflow!


                                                                                                              • Please be sure to answer the question. Provide details and share your research!

                                                                                                              But avoid



                                                                                                              • Asking for help, clarification, or responding to other answers.

                                                                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                                                                              To learn more, see our tips on writing great answers.




                                                                                                              draft saved


                                                                                                              draft discarded














                                                                                                              StackExchange.ready(
                                                                                                              function () {
                                                                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3684311%2frails-how-to-chain-scope-queries-with-or-instead-of-and%23new-answer', 'question_page');
                                                                                                              }
                                                                                                              );

                                                                                                              Post as a guest















                                                                                                              Required, but never shown





















































                                                                                                              Required, but never shown














                                                                                                              Required, but never shown












                                                                                                              Required, but never shown







                                                                                                              Required, but never shown

































                                                                                                              Required, but never shown














                                                                                                              Required, but never shown












                                                                                                              Required, but never shown







                                                                                                              Required, but never shown







                                                                                                              Popular posts from this blog

                                                                                                              Florida Star v. B. J. F.

                                                                                                              Danny Elfman

                                                                                                              Lugert, Oklahoma