Module: ActiveRecord::QueryMethods
- Defined in:
- lib/by2/ext/active_record.rb
Defined Under Namespace
Classes: OrChain
Instance Method Summary collapse
-
#or(opts = :chain, *rest) ⇒ Object
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments, joining WHERE clauses with OR operand, contrary to the default behaviour that uses AND.
-
#where_ast ⇒ Object
Returns an Arel AST containing only where_values.
Instance Method Details
#or(opts = :chain, *rest) ⇒ Object
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments, joining WHERE clauses with OR operand, contrary to the default behaviour that uses AND.
#or accepts conditions in one of several formats. In the examples below, the resulting SQL is given as an illustration; the actual query generated may be different depending on the database adapter.
without arguments
If #or is used without arguments, it returns an ActiveRecord::OrChain object that can be used to chain queries with any other relation method, like where:
Post.where("id = 1").or.where("id = 2")
# SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'id = 2'))
It can also be chained with a named scope:
Post.where("id = 1").or.containing_the_letter_a
# SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'body LIKE \\'%a%\\''))
ActiveRecord::Relation
When #or is used with an ActiveRecord::Relation as an argument, it merges the two relations, with the exception of the WHERE clauses, that are joined using the OR operand.
Post.where("id = 1").or(Post.where("id = 2"))
# SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'id = 2'))
anything you would pass to #where
#or also accepts anything that could be passed to the #where method, as a shortcut:
Post.where("id = 1").or("id = ?", 2)
# SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'id = 2'))
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/by2/ext/active_record.rb', line 69 def or(opts = :chain, *rest) if opts == :chain OrChain.new(self) else left = with_default_scope right = (ActiveRecord::Relation === opts) ? opts : klass.unscoped.where(opts, rest) unless left.where_values.empty? || right.where_values.empty? left.where_values = [left.where_ast.or(right.where_ast)] right.where_values = [] end left = left.merge(right) end end |
#where_ast ⇒ Object
Returns an Arel AST containing only where_values
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/by2/ext/active_record.rb', line 87 def where_ast arel_wheres = [] where_values.each do |where| arel_wheres << (String === where ? Arel.sql(where) : where) end return Arel::Nodes::And.new(arel_wheres) if arel_wheres.length >= 2 if Arel::Nodes::SqlLiteral === arel_wheres.first Arel::Nodes::Grouping.new(arel_wheres.first) else arel_wheres.first end end |