3.0.4 change to chained where methods. Documentation?

I’ve noticed a rather insidious 3.0.4 change to the way that chained
where methods that reference the same attribute are handled. Does
anyone know where I can find more information about where/when this
change came in, and the justification for it? I haven’t been able to
find a changelog mentioning this modification.

Essentially, when you chain two where methods together that reference
the same attribute, the SQL query generated uses an OR on that
attribute, rather than AND.

Example:

Rails 3.0.3
State.where(:abbreviation => ‘TX’).where(:abbreviation => ‘NE’)
SQL: SELECT states.* FROM states WHERE (states.abbreviation =
‘TX’) AND (states.abbreviation = ‘NE’)

Rails 3.0.4
State.where(:abbreviation => ‘TX’).where(:abbreviation => ‘NE’)
SQL: SELECT states.* FROM states WHERE (states.abbreviation =
‘TX’ OR states.abbreviation = ‘NE’)

On 14 February 2011 21:03, Jeremy removed_email_address@domain.invalid wrote:

Example:

Rails 3.0.3
State.where(:abbreviation => ‘TX’).where(:abbreviation => ‘NE’)
SQL: SELECT states.* FROM states WHERE (states.abbreviation =
‘TX’) AND (states.abbreviation = ‘NE’)

Rails 3.0.4
State.where(:abbreviation => ‘TX’).where(:abbreviation => ‘NE’)
SQL: SELECT states.* FROM states WHERE (states.abbreviation =
‘TX’ OR states.abbreviation = ‘NE’)

I can confirm I see the same issue on 3.0.4 (not tried on 3.0.3). It
looks like a bug to me.

Colin

It may seem a bit odd with the where method chained twice like that, but
the query with the OR (Rails 3.0.4) will probably get you the result you
want whereas the query with the AND (Rails 3.0.3) will return 0 records
at all times (because the same attribute can’t have two values).

On 16 February 2011 09:44, Colin L. removed_email_address@domain.invalid wrote:

useful, query may also be encoded wrongly. The principle of chained
I will post on rails-core to see what the response is there.
I posted to rails-core and apparently it is by design rather than a
bug. The question seems to have stirred up a bit of a furore however,
see
http://groups.google.com/group/rubyonrails-core/browse_thread/thread/407f746fd1de6636

Colin

Thanks for posting that link :slight_smile:

After reading a bit more I tend to agree with you that chaining where
multiple times should result in an AND, and not in an OR (even though
the example of doing a .where on the same attribute twice is a little
silly)

On 16 February 2011 05:42, Mark K. removed_email_address@domain.invalid wrote:

It may seem a bit odd with the where method chained twice like that, but the
query with the OR (Rails 3.0.4) will probably get you the result you want
whereas the query with the AND (Rails 3.0.3) will return 0 records at all
times (because the same attribute can’t have two values).

I disagree that OR is the result one would want if one were to code
this. I agree it is apparently a useless query and obviously one
would not code it exactly like this. If the sql for this is
incorrectly generated however, it is likely that a more subtle, and
useful, query may also be encoded wrongly. The principle of chained
where is that the first one is performed, then the next is performed
on the results of the first. At least that is how I understand it.

Consider:
State.where(:abbreviation => ‘TX’).where(“abbreviation = ‘NE’”)
This (correctly in my view) uses AND in the query.
As 3.0.4 stands at the moment the above yields a different result to
State.where(:abbreviation => ‘TX’).where(:abbreviation => ‘NE’)
which seems incorrect to me.

I will post on rails-core to see what the response is there.

Colin

On 16 February 2011 11:43, Colin L. removed_email_address@domain.invalid wrote:

incorrectly generated however, it is likely that a more subtle, and

I will post on rails-core to see what the response is there.

I posted to rails-core and apparently it is by design rather than a
bug. The question seems to have stirred up a bit of a furore however,
see
http://groups.google.com/group/rubyonrails-core/browse_thread/thread/407f746fd1de6636

I see this has now been fixed in the Rails 3.0.5, though I have not
tried it myself yet.

Thanks to Jeremy for finding it in the first place.

Colin