squeel icon indicating copy to clipboard operation
squeel copied to clipboard

#where returns WhereChain when block returns an association's sifter (Rails 4)

Open odedniv opened this issue 11 years ago • 28 comments

Example to reproduce:

class User < ActiveRecord::Base
  sifter(:anonymous) { email == nil }
end

class Post < ActiveRecord::Base
  belongs_to :user
end

This code will fail:

> Post.joins(:user).where{user.sifter(:anonymous)}.to_sql
undefined method `to_sql' for #<ActiveRecord::QueryMethods::WhereChain:0x00000005996c18>

But this code won't:

> Post.joins(:user).where{user.sifter(:anonymous) & `1 = 1`}.to_sql
=> "SELECT `posts`.* FROM `posts` INNER JOIN `posts`.`user_id` = `users`.`id` WHERE ((`users`.`email` IS NULL AND 1 = 1))"

This won't either:

> User.where{sifter(:anonymous)}.to_sql
=> "SELECT `users`.* FROM `users` WHERE (`users`.`email` IS NULL)"

All these pieces of code used to work on Rails 3.2. Haven't debugged it, if you need more information please let me know.

odedniv avatar Nov 21 '13 18:11 odedniv

+1

tispratik avatar Nov 30 '13 00:11 tispratik

Running into the same issue with Rails 4.

@section = current_business.sections.find(params[:section_id])
@products = @section.products.where{ kind.eq(my{ params[:kind] }) }

In jbuilder.

json.array! @products do |product|
  json.partial!('product', product: product)
end

Error:

undefined method `map' for #<ActiveRecord::QueryMethods::WhereChain:0x007fcd09b54c70>

Never saw this in Rail 3.2

anthonator avatar Dec 03 '13 20:12 anthonator

+1

jfeldstein avatar Jan 18 '14 18:01 jfeldstein

Same for me with the following request:

 User.where(id > 10).update_all(updated_at: Date.current)

Error:

 NoMethodError - undefined method `update_all' for #<ActiveRecord::QueryMethods::WhereChain:0x0000010a9656a8>:

benebrice avatar Feb 19 '14 10:02 benebrice

@benebrice Could you try:

User.where{ id > 10 }.update_all(updated_at: Date.current)

Notice that where is using a block.

anthonator avatar Feb 19 '14 14:02 anthonator

@anthonator I tried that too. Same error. Thank you for trying.

benebrice avatar Feb 19 '14 14:02 benebrice

This is weird, though not the same bug I reported...

odedniv avatar Feb 23 '14 09:02 odedniv

@benebrice Are you using AR 4.1? I think that's the error I saw before I started making changes.

chewi avatar Feb 23 '14 09:02 chewi

@chewi I'm using Rails 4.0.2. Maybe that's the problem.

benebrice avatar Feb 23 '14 10:02 benebrice

@benebrice Nah, that version should work fine. It's 4.1 that's broken.

chewi avatar Feb 23 '14 10:02 chewi

@chewi It seems that a lot of methods cannot work with results coming from a "where" request. I have just tried an "includes" :

 NoMethodError - undefined method `includes' for #<ActiveRecord::QueryMethods::WhereChain:0x00000111028ef8>:

And a "collect" :

 NoMethodError - undefined method `collect' for #<ActiveRecord::QueryMethods::WhereChain:0x00000103f6c788>:

Obviously, these methods are not used on empty results.

Edit : doc of WhereChain.Does it means that no more methods can be applied of where results ?!

Edit 2 : "includes" method seems work if you do it like : Model.includes(...).where(...) and not Model.where(...).includes(...)

benebrice avatar Feb 25 '14 22:02 benebrice

It was completely my mistake. The gem squeel was missing... Just add it. Bundle install. And everything was ok. I hope this huge mistake will help someone else.

Regards.

benebrice avatar Feb 26 '14 10:02 benebrice

Clarification for followups: the above comments are not related with the actual issue posted and therefore this issue should not be closed yet.

Thanks

odedniv avatar Feb 26 '14 12:02 odedniv

Just ran into the original issue reported here myself. It's hard to see what's going on because there's a lot of voodoo in Squeel but it's definitely not calling visit_Squeel_Nodes_Sifter when it should. This may be a symptom rather than a cause though.

chewi avatar Mar 10 '14 11:03 chewi

I don't know if this problem exists right now because I tested #315 and found it fixed. Could you please try the latest master branch? Thank you very much.

bigxiang avatar Jul 16 '14 09:07 bigxiang

Maybe It could be closed, if anyone reports this again, I will reopen, thank you every one :)

bigxiang avatar Aug 01 '14 03:08 bigxiang

@bigxiang sorry for the delay, but I tested it and it still fails with the latest 1.2.1 and master. Please note that most of the comments here, including #315 are not the bug I'm experiencing. My bug report is very specific: using an association's sifter in a where block, without any other condition (such as adding & 1 = 1``) causes the #where to return a ActiveRecord::QueryMethods::WhereChain.

Thanks for your support

odedniv avatar Oct 31 '14 09:10 odedniv

@fahad86, that's not a valid SQL. Whatever goes inside squeel must be a valid SQL with a squeel format. Your example: where{exists(Building.new_buildings.where{city_id == cities.I'd})}

@bigxiang can this issue be reopened?

odedniv avatar Nov 25 '14 06:11 odedniv

@odedniv Thanks for replying, I will reopen it, sorry to delay the response. I am too busy recently :)

bigxiang avatar Nov 25 '14 07:11 bigxiang

I have the same problem with Rails 4.1.6 - exactly as @odedniv described it. (tested agaist latest master as well as latest stable)

marcusg avatar Mar 09 '15 15:03 marcusg

Yep, this is actually happens also on 4.2. @marcusg my usual fix is to add & 1=1`` in the end =/

odedniv avatar Mar 10 '15 07:03 odedniv

@odedniv Yes, I'll use this workaround, thanks!

marcusg avatar Mar 10 '15 08:03 marcusg

I'm having the same error on Rails 4.2.

This code:

    query.where do
      client.sift(:has_phone_number)
    end

Throws:

NoMethodError: private method `load' called for #<ActiveRecord::QueryMethods::WhereChain:0x000001111f1c58>`

Changing it to:

    query.where do
      client.sift(:has_phone_number) & `1=1`
    end

Fixes the problem.

Horrible hack, but it does work for now.

CyborgMaster avatar May 15 '15 21:05 CyborgMaster

I met same problem with Rails 4.2.3. This problem is fixed after upgrading to master (and arel are also upgraded to 6.0.3 from 6.0.0)

AknEp avatar Aug 05 '15 01:08 AknEp

@ernie why don't you release latest master?

AknEp avatar Aug 05 '15 01:08 AknEp

I don't know if this is relevant or not but the problem is due to this function here:

https://github.com/rails/rails/pull/21504

ioquatix avatar Sep 04 '15 23:09 ioquatix

Hey, so that PR was merged which should fix this bug.. For anyone who can't update.. here is a monkey patch:

module ActiveRecord::QueryMethods
    def where(opts = :chain, *rest)
        if :chain == opts
            WhereChain.new(spawn)
        elsif opts.blank?
            self
        else
            spawn.where!(opts, *rest)
        end
    end
end

ioquatix avatar Sep 04 '15 23:09 ioquatix

I didn't find that the ActiveRecord::QueryMethods#where monkey patch fixed this bug in our use case, but 1=1 did.

benjaminoakes avatar Jan 09 '17 19:01 benjaminoakes