2. Slides Twitter My blog
Arel http://bit.ly/ggrc-arel brynary brynary.com
3. Agenda
1. What is Arel?
2. Relational Algebra 101
3. Arel with ActiveRecord 3
4. Arel under the Hood
5. Future Possibilities
Arel http://bit.ly/ggrc-arel brynary brynary.com
4. What is Arel?
*
* Mermaids do not query databases.
(Thanks, Carl)
Arel http://bit.ly/ggrc-arel brynary brynary.com
5. What is Arel?
• An object-oriented interpretation of
relational algebra in Ruby
• Written by Nick Kallen (Twitter)
• First commit: December 30, 2007
• Not an ORM!
• http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/
Arel http://bit.ly/ggrc-arel brynary brynary.com
23. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
<!‐‐ View ‐‐>
<ul>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
24. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end Query does not run yet
<!‐‐ View ‐‐>
<ul>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
25. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
SELECT * FROM users WHERE city = 'NYC'
<!‐‐ View ‐‐>
<ul>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
26. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
<!‐‐ View ‐‐>
<ul>
<% cache("nycrb_people") do %>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
27. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
<!‐‐ View ‐‐> Cache hit
<ul>
<% cache("nycrb_people") do %>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
28. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
<!‐‐ View ‐‐>
<ul> Block is not run
<% cache("nycrb_people") do %>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
29. Lazy
# Controller
class RubyistsController
def nycrb
@nycrb = Rubyist.where(:city => "NYC")
end
end
<!‐‐ View ‐‐>
<ul> SELECT never run
<% cache("nycrb_people") do %>
<% @nycrb.each do |user| %>
<li><%= user.name %></li>
<% end %>
<% end %>
</ul>
Arel http://bit.ly/ggrc-arel brynary brynary.com
30. New Finder Methods
• where • offset
• having • joins
• select • includes
• group • lock
• order • readonly
• limit • from
Arel http://bit.ly/ggrc-arel brynary brynary.com
44. Exposing the Attributes
class ActiveRecord::Base
def self.[](column_name)
arel_table[column_name]
end
end
Arel http://bit.ly/ggrc-arel brynary brynary.com
49. Map any relation to a class
class Signup < ActiveRecord::Base
users = Arel::Table.new(:users)
emails = Arel::Table.new(:emails)
set_relation users_table.
join(emails).
on(users[:email_id].eq(emails[:id]))
end
Arel http://bit.ly/ggrc-arel brynary brynary.com
50. May any relation as an association
class User
orders = Arel::Table.new(:orders)
last_orders_by_user = orders.
group(orders[:user_id]).
project(orders[:id].maximum.as(:id))
has_one :last_order, orders.
where(orders[:id].in(last_orders_by_user[:id]))
end
User.includes(:last_order).each do |user|
# ...
end
Arel http://bit.ly/ggrc-arel brynary brynary.com
59. Thank You
Arel http://bit.ly/ggrc-arel brynary brynary.com
Hinweis der Redaktion
How many people have heard of Arel?
Lots of contributors!!!
Math concept. Offshoot of set theory. E.F. Codd in 1970
You use relation algebra when you use SQL.
Header with columns and types.
A set of tuples.
Not SQL specific.
...But: think about tables, views, query results
...in AR: classes, associations
Selection: WHERE (restrict a set)
Projection: Limit the columns (SELECT ...)
Like SQL
Set operations
Operations on relations yield new relations.
Implemented in code as the composite pattern.
Note: This works because relations are immutable, which is cool.
Cleaned up ActiveRecord. Nice new Syntax for you.
Query runs on iteration
Cleans up everything quite nicely
Caution!
Not supported by Rails. Don&#x2019;t report bugs ;-)
Subject to Arel API changes
Contrived example.
Consider your code that builds queries based on data.
AR becomes a Data Mapper
Arel is split into Algebra and Engines
Arel supports multiple engines
Each engine defines CRUD operations
Write an ActiveRecord relation that pulls IDs from Redis and records from a table