Reputation: 526
I have the following situation in my Rails app. There are two models, let's say User and Company:
class User < ActiveRecord::Base
belongs_to :company
default_scope -> {where(removed_at: nil)}
end
and
class Company < ActiveRecord::Base
has_many :users
end
What I want now is loading an Company record and include the Users
Company.unscoped.all.includes(:users)
What will result in a query to the users table which includes the default-scope. So I get the Company record with all not removed users prefetched. But in this case I do also want the Users where removed_at is not null (=> the removed User records). The "unscoped" method is only applied to the Company model, not to the User model.
Is there any way to do this? Thanks for any ideas!
Upvotes: 7
Views: 7528
Reputation: 26487
The relation is not preserving this state, when accessing it later (Rails 6.0)
A possible workaround for some cases is forcing the resolution, e.g.:
User.unscoped { Company.includes(:users).to_a }
to_a
resolves the relation while in the block, so the scope is effectively removed.
Upvotes: 3
Reputation: 930
I had a greatly-branched STI models set. So the only approach, which works for me (Rails 4.2.5) is the following:
class UndeadUser < ActiveRecord::Base
self.table_name = 'users'
end
class User < UndeadUser
# real logic here
end
class Employee < User; end
class Manager < Employee; end
# grouping model
class Organization < ActiveRecord::Base
has_many :employees
has_many :users, class: UndeadUsers
before_destroy :really_destroy_users_and_data! # in case of using acts_as_paranoid or paranoia gems it might be helpful
end
Solution from @abstractcoder doesn't work for me, because rails try to add WHERE users.type IN ('UndeadUser')
when UndeadUser inherited from User.
Upvotes: 0
Reputation: 376
Here is the solution I got working in my Rails 4.0 application
class User < ActiveRecord::Base
belongs_to :company
default_scope -> {where(removed_at: nil)}
end
class UserUnscoped < User
self.default_scopes = []
end
class Company < ActiveRecord::Base
has_many :users, class_name: "UserUnscoped"
end
Company.unscoped.all.includes(:users)
Upvotes: 4
Reputation: 4367
This method accepts a block. All queries inside the block will not use the default_scope:
User.unscoped { Company.includes(:users).all }
or:
User.unscoped do
Company.includes(:users).all
end
Upvotes: 3