Michael Pearson
2012-Dec-16 05:22 UTC
AR scope chaining with merged keys violates principle of least surprise
Github issue: https://github.com/rails/rails/issues/8511
As I''ve just discovered that this behaviour is by design, I''d
like to
discuss it here rather than on github.
AR''s merge behaviour when scopes are chained, as described in the test
a
https://github.com/rails/rails/blob/master/activerecord/test/cases/named_scope_test.rb#L327,
is confusing.
For example, the following will produce different queries:
class MyModel < ActiveRecord::Base
scope :successful, where(:success => true)
end
MyModel.where("success = 0").successful => "WHERE success=0
AND success=1"
MyModel.where(:success => false).successful => "WHERE success =
1"
MyModel.where(:success => false).where(:success => true) => "WHERE
success=0 AND success=1"
Two of the above behaviours are "surprising":
- a chained scope will override a previously specified where condition
- specifying the where() condition instead of the scope behaves
differently than simply calling the scope
I discovered this while when preparing an AR relation for a report -
attempting to call scopes on that relation to provide a report summary (eg,
% of successful queries) gave me unexpected results, especially when that
relation is generated from user queries passed to the report (eg, only show
unsuccessful queries).
I can see how this behaviour, in certain situations, could be desirable. I
also expect that people already depend on this behaviour. As such, I do not
have any great ideas on how to "fix" it.
I would like to discuss the reason behind this behaviour and ways that it
can be made more obvious to the user so that it doesn''t trip others up.
Here are my ideas so far:
- Log a warning when a scope overrides a key in a previous scope
- Add a flag to the relation that forces merges to not occur
(MyModel.filtered.etc ?)
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-core/-/MfHTH2qZxREJ.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.