Unscoped Associations
Have you ever needed to skip the default_scope
when fetching objects through associations methods (for some strange reasons)? Do it easily with this Active Record
extension!
Supported associations:
:belongs_to
:has_one
:has_many
Officially supported (tested) Active Record
versions: 3.2, 4.0, 4.1, 4.2 and 5.0.
Installation
Add this line to your Gemfile:
gem 'unscoped_associations'
Or install the gem manually:
gem install unscoped_associations
Usage
Basic usage example:
class User < ActiveRecord::Base
has_many :comments
has_many :all_comments, class_name: 'Comment', unscoped: true
default_scope { where(active: true) }
end
class Comment < ActiveRecord::Base
belongs_to :user, unscoped: true
default_scope { where(public: true) }
end
From now on, you get:
-
@user.comments
: returns all public comments -
@user.all_comments
: returns all comments skipping the default_scope -
@comment.user
: returns the user without taking account the 'active' flag
Status
This project was originally thought and built for a Rails 3.2 application.
Rails 4 introduces some updates regarding associations. For example, since Rails 4 (AR 4 to be precise), you are able to customize associations using a scope block (overriding conditions), so you can skip the default_scope
conditions by:
class User < ActiveRecord::Base
has_many :all_comments, -> { where(public: [true, false]) }, class_name: 'Comment'
end
Since Rails 4.1, you can also override the default conditions using the unscope
method:
class User < ActiveRecord::Base
has_many :all_comments, -> { unscope(where: :public) }, class_name: 'Comment'
end
Anyway, you can continue using unscoped_associations
, could be useful in certain situations, for example, if you prefer to bypass the entire default_scope
, given a scope with multiple conditions, like:
default_scope { where(public: true, deleted_at: nil).order(:updated_at) }
Rails 5.0 is also supported as a migration path to facilitate upgrades.
Notes
- Under the hood, Unscoped Associations relies on the
unscoped
method (from AR). So, chaining unscoped associations with other AR query methods won't work. E.g.:@user.all_comments.count
will load comments with thedefaul_scope
applied. In this case,@user.all_comments.to_a.count
should work. - Unscoped Associations doesn't touch the preloading layer, so
includes
,joins
, ... in combination with an unscoped association can causeN+1
problems.
Contributing
Any kind of fixes, both code and docs, or enhancements are really welcome!
To contribute, just fork the repo, hack on it and send a pull request. Don't forget to add specs for behaviour changes and run the tests by:
bundle exec rspec
bundle exec appraisal rspec # run against all supported AR versions
License
Copyright (c) Marc Anguera. Unscoped Associations is released under the MIT License.