This project is archived and is in readonly mode.
with_exclusive_scope does not override the default_scope when each provides IS NULL / IS NOT NULL conditions
Reported by foca | February 1st, 2010 @ 10:36 PM | in 3.0.2
class Page < ActiveRecord::Base
default_scope where(:deleted_at => nil)
def self.deleted
with_exclusive_scope :find => where('pages.deleted_at IS NOT NULL') do
self
end
end
end
Page.all
emits this SQL:
SELECT "pages".* FROM "pages" WHERE ("pages"."deleted_at" IS NULL)
While Page.deleted.all
emits this:
SELECT "pages".* FROM "pages" WHERE ("pages"."deleted_at" IS NULL) AND ("pages"."deleted_at" IS NOT NULL)
Attached is a failing test.
Comments and changes to this ticket
-
José Valim February 3rd, 2010 @ 10:08 AM
- Assigned user set to Pratik
- Milestone cleared.
-
Neeraj Singh June 28th, 2010 @ 10:22 PM
- Tag changed from activerecord, rails3 to activerecord, patch, rails3
- Assigned user changed from Pratik to José Valim
- State changed from new to open
- Importance changed from to Low
Attached is code patch and test as discussed with José Valim.
-
Repository June 29th, 2010 @ 12:18 AM
- State changed from open to resolved
(from [40e87ac66912b06c31c98b057a49c64f5555dd99]) with_exclusive_scope does not work properly if ARel is passed. It does work nicely if hash is passed. Blow up if user is attempting it pass ARel to with_exclusive_scope.
[#3838 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/40e87ac66912b06c31c98b057a49c6... -
Pratik June 29th, 2010 @ 12:46 AM
- State changed from resolved to open
How is the issue originally raised by foca is related to the new finder syntax and the commit above ?
The below would have the same issue.
class Page < ActiveRecord::Base default_scope :conditions => {:deleted_at => nil} def self.deleted with_exclusive_scope :find => where('pages.deleted_at IS NOT NULL') do self end end end
-
Neeraj Singh June 29th, 2010 @ 02:16 AM
The commit above will make the code blow up. This ensures that you are not getting the wrong result.
Above code will blow up with following message.
ARel can not be used with_exclusive_scope. You can either specify hash style conditions to with_exclusive_scope like this: User.with_exclusive_scope {:find => :conditions => {:active => true} } do end Or you can use unscoped method instead of with_exclusive_scope like this: User.unscoped.where(:active => true) do end
The fix is not ideal. However I am not able to find a decent way to fix this without changing the fundamental way how default_scope is currently applied.
Ideally the arel returned should not have default_scope applied and the default_scope should be applied at the very end and not at the very beginning which is the case right now.
-
José Valim June 29th, 2010 @ 09:08 AM
Pratik, the reason why his code is failing is because when you call
where('pages.deleted_at IS NOT NULL')
, it's still outside thewith_exclusive_scope
method and consequently this new relation is created on top of the default_scope.That said, the with_exclusive_scope syntax cannot work with relations. This is not due to how with_exclusive_scope works, but how relations are created. So we chose to raise a warning if the user gives a relation to with_exlusice_scope, telling him to use unscoped instead. Which is simpler and works as well.
Notice that, if you give hash conditions, it would work (as Neeraj said):
User.with_exclusive_scope {:find => :conditions => {:active => true} } do end
And I think moving from with_exclusive_scope to unscoped is a good change, because it's a simpler syntax (as you moved most of ActiveRecord internals to use it as well instead of with_exclusive_scope).
-
José Valim June 29th, 2010 @ 11:03 AM
Just one note, in Neeraj comment above, you don't need to pass a block to where (that syntax does not work). The correct is just to call unscoped:
User.unscoped.where(:active => true)
-
José Valim June 29th, 2010 @ 04:45 PM
- State changed from open to resolved
Please check this commit for more examples:
http://github.com/rails/rails/commit/bd1666ad1de88598ed6f04ceffb848...
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>