Skip to content

Instantly share code, notes, and snippets.

@tetz-akaneya
Last active September 8, 2018 02:42
Show Gist options
  • Save tetz-akaneya/037e719d86b216313be681c7b272230d to your computer and use it in GitHub Desktop.
Save tetz-akaneya/037e719d86b216313be681c7b272230d to your computer and use it in GitHub Desktop.
RailsのArelを調査してみた ref: https://qiita.com/valley/items/9ac200acbccc46b2ea44
# Arel::Noees::Orの親クラス
def initialize left, right
super()
@left = left
@right = right
end
users = Arel::Table.new(:users)
query = users.project("id").where(users[:age].gt(20).and(users[:age].lt(30))).order("id")
query.to_sql
# "SELECT id FROM \"users\" WHERE \"users\".\"age\" > 20 AND \"users\".\"age\" < 30 ORDER BY id"
new_node = left_node.create_node(right_node)
new_node.left == left_node # true
new_node.right == right_node # true
users = Arel::Table.new(:usrs)
users.where(
users[:age].eq(20).or(users[:age].eq(18)).and(users[:age].gt(15))
)
users.age = 20 OR users.age =18 AND users.age > 15
users.from.to_sql # "SELECT FROM \"users\""
users[:age].eq(20).or(users[:age].eq(18)).and(users[:age].gt(15)).to_sql
# "(\"users\".\"age\" = 20 OR \"users\".\"age\" = 18) AND \"users\".\"age\" > 15"
eql_node = users[:age].eq(20)
eql_node.class # Arel::Nodes::Equality
eql_node.left
# <struct Arel::Attributes::Attribute relation=#<Arel::Table:0x007fd378afb1c8 @name="users", @type_caster=nil, @table_alias=nil>, name=:age>
eql_node.right
# <Arel::Nodes::Casted:0x007fd37a401118 @val=20, @attribute=#<struct Arel::Attributes::Attribute relation=#<Arel::Table:0x007fd378afb1c8 @name="users", @type_caster=nil, @table_alias=nil>, name=:age>>
def or right
Nodes::Grouping.new Nodes::Or.new(self, right)
end
def project *projections
# FIXME: converting these to SQLLiterals is probably not good, but
# rails tests require it.
@ctx.projections.concat projections.map { |x|
STRING_OR_SYMBOL_CLASS.include?(x.class) ? Nodes::SqlLiteral.new(x.to_s) : x
}
self # 自分を返している = チェーン可能
end
def from
SelectManager.new(self)
end
def where condition
from.where condition
end
def project *things
from.project(*things)
end
# Arel::SelectManagerの親クラス
def where expr
if Arel::TreeManager === expr
expr = expr.ast
end
@ctx.wheres << expr
self # 自分を返している = チェーン可能
end
users[:age].eq(20).or(users[:age].eq(18))
users[:age].eq(20).or(users[:age].eq(18)).and(users[:age].gt(15))
users[:age].eq(20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment