squeel icon indicating copy to clipboard operation
squeel copied to clipboard

functions do not allow predicates as arguments

Open mckinnsb opened this issue 10 years ago • 1 comments

I have the following scope:

def self.ready_to_be_reauthorized                                                                                                                                                                                                                                                                                                                                        
  with_state( :delivered ).                                                                                                                                                                                                                                                                                                                                              
    online.                                                                                                                                                                                                                                                                                                                                                              
    joins { order_items.product_inventory.product }.                                                                                                                                                                                                                                                                                                                             having {                                                                                                                                                                                                                                                                                                                                                             
             bool_and( order_items.weight.not_eq( nil ) | product.catch_weight.eq( false ) )                                                                                                                                                                                                                                                                                            }.                                                                                                                                                                                                                                                                                                                                                            
    group { id }
end

Which is trying to execute the following ( valid ) SQL ( in Postgres ):

SELECT "orders".* FROM "orders"                                                                                                                                                                                                                                                                                                                                          
  INNER JOIN "order_items" ON "order_items"."order_id" = "orders"."id"                                                                                                                                                                                                                                                                                                   
  INNER JOIN "product_inventories" ON "product_inventories"."id" = "order_items"."product_inventory_id"                                                                                                                                                                                                                                                                  
  INNER JOIN "products" ON "products"."id" = "product_inventories"."product_id"                                                                                                                                                                                                                                                                                          
  WHERE ("orders"."state" IN ('delivered')) AND (( orders.payment_token != 'offline' AND orders.payment_token IS NOT NULL ))                                                                                                                                                                                                                                             
  GROUP BY "orders"."id"                                                                                                                                                                                                                                                                                                                                                 
  HAVING bool_and("products"."catch_weight" = 't' OR "order_items"."weight" IS NOT NULL ); 

Executing it gives the following error in Ruby:

  TypeError: Cannot visit Squeel::Nodes::Or                                                                                                                                                                                                                                                                                                                                
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/arel-5.0.1.20140414130214/lib/arel/visitors/visitor.rb:28:in `rescue in visit'                                                                                                                                                                                                                                    
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/arel-5.0.1.20140414130214/lib/arel/visitors/visitor.rb:22:in `visit'                                                                                                                                                                                                                                              
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/arel-5.0.1.20140414130214/lib/arel/visitors/visitor.rb:5:in `accept'                                                                                                                                                                                                                                              
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:169:in `quote'                                                                                                                                                                                                                                                        
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:391:in `block in visit_Squeel_Nodes_Function'                                                                                                                                                                                                                         
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:378:in `map'                                                                                                                                                                                                                                                          
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:378:in `visit_Squeel_Nodes_Function'                                                                                                                                                                                                                                  
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:182:in `visit'                                                                                                                                                                                                                                                        
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:197:in `rescue in visit!'                                                                                                                                                                                                                                             
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:195:in `visit!'                                                                                                                                                                                                                                                       
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:225:in `block in visit_Array!'                                                                                                                                                                                                                                        
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:225:in `map'                                                                                                                                                                                                                                                          
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:225:in `visit_Array!'                                                                                                                                                                                                                                                 
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:195:in `visit!'                                                                                                                                                                                                                                                       
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/visitors/visitor.rb:31:in `accept!'                                                                                                                                                                                                                                                       
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/adapters/active_record/4.1/relation_extensions.rb:173:in `block (3 levels) in <module:RelationExtensions>'                                                                                                                                                                                
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/adapters/active_record/4.1/relation_extensions.rb:170:in `each'                                                                                                                                                                                                                           
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/adapters/active_record/4.1/relation_extensions.rb:170:in `block (2 levels) in <module:RelationExtensions>'                                                                                                                                                                                
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/squeel-1.2.3/lib/squeel/adapters/active_record/4.1/relation_extensions.rb:83:in `build_arel'                                                                                                                                                                                                                      
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/activerecord-4.1.10/lib/active_record/relation/query_methods.rb:842:in `arel'                                                                                                                                                                                                                                     
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/activerecord-4.1.10/lib/active_record/relation.rb:611:in `exec_queries'                                                                                                                                                                                                                                           
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/activerecord-4.1.10/lib/active_record/relation.rb:493:in `load'                                                                                                                                                                                                                                                   
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/activerecord-4.1.10/lib/active_record/relation.rb:238:in `to_a'                                                                                                                                                                                                                                                   
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/bullet-4.14.5/lib/bullet/active_record41.rb:10:in `to_a'                                                                                                                                                                                                                                                          
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/activerecord-4.1.10/lib/active_record/relation.rb:602:in `inspect'                                                                                                                                                                                                                                                
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/console.rb:90:in `start'                                                                                                                                                                                                                                                       
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/console.rb:9:in `start'                                                                                                                                                                                                                                                        
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:69:in `console'                                                                                                                                                                                                                                              
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:40:in `run_command!'                                                                                                                                                                                                                                         
        from /home/stew/spolsky/vendor/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands.rb:17:in `<top (required)>'                                                                                                                                                                                                                                                    

This feels like a bug to me. bool_and is supposed to accept any type of expression that's valid within the rows selected, and all I am doing is or'ing two fairly straightforward expressions ( each of which resolve fine within having{} on their own ).

Is there something obvious I am missing here?

Is this not supported in Squeel/is this a bug? If so, is there another way?

Thanks!

mckinnsb avatar Jun 09 '15 15:06 mckinnsb

I guess this is a Predicate and Functions can't receive Predicates in the DSL?

mckinnsb avatar Jun 09 '15 17:06 mckinnsb