What edge_rider offers you

Updated . Posted . Visible to the public.

edge_rider is Power tools for ActiveRecord relations (scopes). Please note that some of the functions edge_rider provides have native implementations in newer rails versions.

Useful in applications

Relation#traverse_association(*names)

Edge Rider gives your relations a method #traverse_association which returns a new relation by "pivoting" around a named association. You can traverse multiple associations in a single call. E.g. to turn a relation of posts into a relation of all posts of their authors:

posts = Post.where(:archived => false)
posts_by_same_authors = posts.traverse_association(:author, :posts)

Model.preload_associations(object, associations)

Edge Rider gives your model classes a method .preload_associations. The method can be used to preload associations for loaded objects like this:

@user = User.find(params[:id])
User.preload_associations [@user], { :threads => { :posts => :author }, :messages => :sender }

Useful in libraries

These utilities are mostly useful in libraries that need to support multiple versions of Rails. They offer a unified interface across Rails versions.

Relation#collect_ids

You should not use relation.collect(&:id) for this because a call like that will instantiate a potentially large number of ActiveRecord objects only to collect its ID.

Edge Rider has a better way. Your relations gain a method #collect_ids that will fetch all IDs in a single query without instantiating a single ActiveRecord object:

posts = Post.where(:archived => false)
post_ids = posts.collect_ids

Implemenation note: In Rails 3.2+, #collect_ids delegates to #pluck, which can be used for the same purpose.

Relation#collect_column(name, options)

You should not use relation.collect(&:column) for this because a call like that will instantiate a potentially large number of ActiveRecord objects only to collect its column value.

Edge Rider has a better way. Your relations gain a method #collect_column that will fetch all column values in a single query without instantiating a single ActiveRecord object. If you only care about unique values, use the :distinct => true option:

posts = Post.where(:archived => false)
distinct_subjects = posts.collect_column(:subject, :distinct => true)

Implementation note: In Rails 3.2+, #collect_column delegates to #pluck, which can be used for the same effect.

Relation#to_sql

# Rails 2 scope
Post.scoped(:conditions => { :id => [1, 2] }).to_sql 
# => "SELECT `posts`.* FROM `posts` WHERE `posts.id` IN (1, 2)"

^

# Rails 3 relation
Post.where(:id => [1, 2]).to_sql 
# => "SELECT `posts`.* FROM `posts` WHERE `posts.id` IN (1, 2)"

Implementation note: Rails 3+ implements #to_sql.

Relation#to_id_query

Site.joins(:user).where(:users => { :name => 'Bruce' }).to_id_query

to_id_query will immediately run an SQL query where it collects all the IDs that match your relation:

SELECT sites.id FROM sites INNER JOIN users WHERE sites.user_id = sites.id AND users.name = 'Bruce'

It now uses these IDs to return a new relation that has no joins and a single condition on the id column:

SELECT * FROM sites WHERE sites.user_id IN (3, 17, 103)

Relation#origin_class

Edge Rider gives your relations a method #origin_class that returns the class the relation is based on. This is useful e.g. to perform unscoped record look-up.

Post.recent.origin_class
# => Post

Model.scoped

Edge Rider ports Model.scoped forward to Rails 4+ (taken from activerecord-deprecated_finders).

User.scoped # just calls User.all in Rails 4
User.active.scoped(conditions: { admin: true })
Dominik Schöler
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2014-08-12 08:43)