🔦 Skip the default_scope in your associations (ActiveRecord)
Ruby
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

Unscoped Associations

Gem Version Build Status

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 the defaul_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 cause N+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.