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.