Created
February 23, 2016 19:07
-
-
Save jagtesh/40f21fd95d25c1b56e24 to your computer and use it in GitHub Desktop.
Arel goodness (with CASE statement) in < v7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Remove this for Arel v7.0 | |
module Arel | |
module Nodes | |
class Case < Arel::Nodes::Node | |
include Arel::OrderPredications | |
include Arel::Predications | |
include Arel::AliasPredication | |
attr_accessor :case, :conditions, :default | |
def initialize expression = nil, default = nil | |
@case = expression | |
@conditions = [] | |
@default = default | |
end | |
def when condition, expression = nil | |
@conditions << When.new(Nodes.build_quoted(condition), expression) | |
self | |
end | |
def then expression | |
@conditions.last.right = Nodes.build_quoted(expression) | |
self | |
end | |
def else expression | |
@default = Else.new Nodes.build_quoted(expression) | |
self | |
end | |
def initialize_copy other | |
super | |
@case = @case.clone if @case | |
@conditions = @conditions.map { |x| x.clone } | |
@default = @default.clone if @default | |
end | |
def hash | |
[@case, @conditions, @default].hash | |
end | |
def eql? other | |
self.class == other.class && | |
self.case == other.case && | |
self.conditions == other.conditions && | |
self.default == other.default | |
end | |
alias :== :eql? | |
end | |
class When < Binary # :nodoc: | |
end | |
class Else < Unary # :nodoc: | |
end | |
end | |
end | |
module Arel | |
module Visitors | |
class DepthFirst < Arel::Visitors::Visitor | |
alias :visit_Arel_Nodes_Else :unary | |
def visit_Arel_Nodes_Case o | |
visit o.case | |
visit o.conditions | |
visit o.default | |
end | |
alias :visit_Arel_Nodes_When :binary | |
end | |
end | |
end | |
module Arel | |
module Predications | |
def when right | |
Nodes::Case.new(self).when quoted_node(right) | |
end | |
end | |
end | |
module Arel | |
module Visitors | |
class ToSql < Arel::Visitors::Reduce | |
def visit_Arel_Nodes_Case o, collector | |
collector << "CASE " | |
if o.case | |
visit o.case, collector | |
collector << " " | |
end | |
o.conditions.each do |condition| | |
visit condition, collector | |
collector << " " | |
end | |
if o.default | |
visit o.default, collector | |
collector << " " | |
end | |
collector << "END" | |
end | |
def visit_Arel_Nodes_When o, collector | |
collector << "WHEN " | |
visit o.left, collector | |
collector << " THEN " | |
visit o.right, collector | |
end | |
def visit_Arel_Nodes_Else o, collector | |
collector << "ELSE " | |
visit o.expr, collector | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment