Works similar to scopes
. Rather than modifying the where clause of the ActiveRecord::Relation
, it creates a common table expression (CTE) to be applied upon execution.
Unlike scopes, they do not affect the values of attributes upon creation.
- Ruby 2.3+
- ActiveRecord 4.2+
Note: Check the builds to be sure your version is in-fact supported. The requirements are left unbounded on the upper constraint for posterity, but may not be gaurenteed to work.
Add this line to your application's Gemfile:
gem 'active_record-framing'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_record-framing
Any ActiveRecord::Base
descendant has access to two additional methods: frame
and default_frame
.
class User < ActiveRecord::Base
default_frame { where(active: true) }
# ...
end
Afterwards, User.all.to_sql
yields
WITH "users" AS
(SELECT "users".* FROM "users" WHERE "users"."active" = true)
SELECT "users".* FROM "users"
class Admin < User
default_frame { where(arel_table[:kind].eq(1)) }
# ...
end
Note: In ActiveRecord
versions less than 5.2
(Arel 9.0
), default_frames
where clauses must be constructed with arel
(arel_table[:column]
etc) for values other than nil
, true
, and false
. This is due to a limitation with what ActiveRecord calls "bind values" (beyond the scope of this document).
Afterwards, Admin.all.to_sql
yields
WITH "users" AS
(SELECT "users".* FROM "users" WHERE "users"."kind" = 1)
Similar to how named_scopes
work in ActiveRecord
, frames can be named:
class User < ActiveRecord::Base
frame :admin, -> { where(arel_table[:kind].eq(1)) }
# ...
end
Named frames are accessed through assigned consts under the original class. This helps avoid collision with scopes, and helps indicate the mutual exclusivity of frames (by design).
User::Admin.all.to_sql
# =>
# WITH "admin/users" AS
# (SELECT "users".* FROM "users" WHERE "users".kind = 1)
# SELECT "admin/users".* FROM "admin/users"
After checking out the repo, run bundle
to install dependencies. Then, run bundle exec rspec
to run the tests.
Bug reports and pull requests are welcome on GitHub at https://github.com/TwilightCoders/active_record-framing. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.