Perhaps or() and where/and (I mainly add `and` because it's symmetrical with `or` and adds a lot of readability IMHO) could take other where() snippets? So your examples become:
r = User.where( :foo => 1 ) r = r.and( r.where( :bar => 1 ).or( :bar => 2 )) ...and... r = User.where( :foo => 1 ).where( :bar => 1 ) r = r.or( :bar => 2 ) ...respectively. On Wed, Feb 16, 2011 at 10:59 AM, Matt Jones <al2o...@gmail.com> wrote: > > On Feb 16, 2011, at 1:22 PM, Jason King wrote: > > > Just want to get this onto the table, "what most people expect" is not > the only measure of a good API choice. > > > > To specifically answer Aaron's question, for #4598, I think the fix for > that would be for subsequent `default_scope`s to just overwrite previous > ones entirely. Not to merge with them. > > > > For the broader question which seems to be what this thread is about, ie. > what to do with: User.where(:foo => 1).where(:foo => 2) how about adding > alias `and` as an alias for `where`, and adding `or` as an alias for "where > that does ORs". So the syntax could be: > > > > User.where(:foo => 1).and(:foo => 2) > > > > And: > > > > User.where(:foo => 1).or(:foo => 2) > > > > I'm sure I don't need to state what SQL each of those turn into (the real > test for a good API :) > > I suspect the 'and' behavior is already pretty well understood as the > result of chaining 'where's. What about an explicit one for the 'or' case: > > User.where(:foo => 1).or_where(:foo => 2) > > The only issue I could see with this syntax is that it's somewhat unclear > what should happen here: > > User.where(:foo => 1).where(:bar => 2).or_where(:bar => 3) > > as it could be interpreted as either > > Version A: (foo = 1 AND bar = 2) OR (bar = 2) > > or > > Version B: (foo = 1) AND (bar = 1 OR bar = 2) > > The issue is especially tricky once you're constructing relations in more > than one place. For instance, this should do something reasonable: > > r = User.where(:foo => 1) > def foo(some_relation) > some_relation.where(:bar => 1).or_where(:bar => 2) # probably expects > version B SQL > end > foo(r) # probably expects version B SQL > > but so should this: > r2 = User.where(:foo => 1).where(:bar => 1) > def other_foo(some_relation) > some_relation.or_where(:bar => 2) > end > other_foo(r2) # probably expects version A SQL > > the difficulty is that the sequence of method calls on the relation are > identical, they're just in different scopes. > > On the other hand, isn't this sort of issue exactly why Arel has operators > to combine scopes? The chained notation is alright for some things, but it's > never going to be sufficient to create arbitrary SQL without a lot of > fussing. > > --Matt Jones > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.