Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help converting a function from non-baby squeel #55

Open
Siggs2000 opened this issue Feb 16, 2017 · 9 comments
Open

Help converting a function from non-baby squeel #55

Siggs2000 opened this issue Feb 16, 2017 · 9 comments

Comments

@Siggs2000
Copy link

I'm tired of battling squeel and was happy to find this! But I'm completely stumped on converting this function into baby_squeel.

In my model, I have this function (it uses some postgis stuff from the rgeo gem)

# latlon is a column on this model and addressable is something I'm going to pass into it
def self.contains(addressable)
  where{st_intersects(:latlon, addressable)}
end

I was hoping to just change where to where.has but that didn't seem to work. Thanks in advance for any help on this!

I'm running rails 4.2.7

@rzane
Copy link
Owner

rzane commented Feb 16, 2017

I'm happy to help, but I'll need a little information than "it didn't work". Did it throw an error? If so, could you provide a backtrace? If not, what SQL was generated?

If latlon is a column, why are you specifying it as a symbol instead of just as the column? For example, where.has { st_intersects(latlon, addressable) }

@Siggs2000
Copy link
Author

Thanks @rzane - I should've been a little more descriptive there.

It seems to be a syntax error. Where the old sqeel way worked for the query (but it broke my caching), this suggested baby_squeel syntax seems to not be executing the same query and so I get an arel error.

The main error is: unsupported: RGeo::Geographic::SphericalMultiPolygonImpl (so it's not interpreting that addressable variable the same way as it was in squeel). The addressable variable is an RGeo object.

The full backtrace is:

--------------

 - arel (6.0.4) lib/arel/visitors/to_sql.rb:736:in `unsupported'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:795:in `block in inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each_with_index'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:766:in `visit_Array'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:795:in `block in inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each_with_index'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:461:in `visit_Arel_Nodes_NamedFunction'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:437:in `visit_Arel_Nodes_Grouping'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:795:in `block in inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each_with_index'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:793:in `inject_join'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:650:in `visit_Arel_Nodes_And'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:255:in `block in visit_Arel_Nodes_SelectCore'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:254:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:254:in `each_with_index'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:254:in `visit_Arel_Nodes_SelectCore'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:210:in `block in visit_Arel_Nodes_SelectStatement'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:209:in `each'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:209:in `inject'
 - arel (6.0.4) lib/arel/visitors/to_sql.rb:209:in `visit_Arel_Nodes_SelectStatement'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:13:in `visit'
 - arel (6.0.4) lib/arel/visitors/reduce.rb:7:in `accept'
 - activerecord (4.2.7) lib/active_record/connection_adapters/abstract/database_statements.rb:12:in `to_sql'
 - activerecord (4.2.7) lib/active_record/connection_adapters/abstract/query_cache.rb:67:in `select_all'
 - activerecord (4.2.7) lib/active_record/querying.rb:39:in `find_by_sql'
 - activerecord (4.2.7) lib/active_record/relation.rb:639:in `exec_queries'
 - activerecord (4.2.7) lib/active_record/relation.rb:515:in `load'
 - activerecord (4.2.7) lib/active_record/relation.rb:243:in `to_a'
 - activerecord (4.2.7) lib/active_record/relation.rb:630:in `inspect'
 - app/controllers/api/v1/listings_controller.rb:148:in `p'
 - app/controllers/api/v1/listings_controller.rb:148:in `polygon_search'
 - actionpack (4.2.7) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
 - actionpack (4.2.7) lib/abstract_controller/base.rb:198:in `process_action'
 - actionpack (4.2.7) lib/action_controller/metal/rendering.rb:10:in `process_action'
 - actionpack (4.2.7) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:117:in `call'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:505:in `call'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:92:in `__run_callbacks__'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:81:in `run_callbacks'
 - actionpack (4.2.7) lib/abstract_controller/callbacks.rb:19:in `process_action'
 - actionpack (4.2.7) lib/action_controller/metal/rescue.rb:29:in `process_action'
 - actionpack (4.2.7) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
 - activesupport (4.2.7) lib/active_support/notifications.rb:164:in `block in instrument'
 - activesupport (4.2.7) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
 - activesupport (4.2.7) lib/active_support/notifications.rb:164:in `instrument'
 - actionpack (4.2.7) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
 - actionpack (4.2.7) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
 - activerecord (4.2.7) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
 - actionpack (4.2.7) lib/abstract_controller/base.rb:137:in `process'
 - actionview (4.2.7) lib/action_view/rendering.rb:30:in `process'
 - actionpack (4.2.7) lib/action_controller/metal.rb:196:in `dispatch'
 - actionpack (4.2.7) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
 - actionpack (4.2.7) lib/action_controller/metal.rb:237:in `block in action'
 - actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:74:in `dispatch'
 - actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:43:in `serve'
 - actionpack (4.2.7) lib/action_dispatch/journey/router.rb:43:in `block in serve'
 - actionpack (4.2.7) lib/action_dispatch/journey/router.rb:30:in `each'
 - actionpack (4.2.7) lib/action_dispatch/journey/router.rb:30:in `serve'
 - actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:817:in `call'
 - rack-pjax (1.0.0) lib/rack/pjax.rb:12:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/flash.rb:260:in `call'
 - warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
 - warden (1.2.7) lib/warden/manager.rb:35:in `catch'
 - warden (1.2.7) lib/warden/manager.rb:35:in `call'
 - rack (1.6.5) lib/rack/etag.rb:24:in `call'
 - rack (1.6.5) lib/rack/conditionalget.rb:38:in `call'
 - rack (1.6.5) lib/rack/head.rb:13:in `call'
 - remotipart (1.3.1) lib/remotipart/middleware.rb:32:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/flash.rb:260:in `call'
 - rack (1.6.5) lib/rack/session/abstract/id.rb:225:in `context'
 - rack (1.6.5) lib/rack/session/abstract/id.rb:220:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/cookies.rb:560:in `call'
 - activerecord (4.2.7) lib/active_record/query_cache.rb:36:in `call'
 - activerecord (4.2.7) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:in `call'
 - activerecord (4.2.7) lib/active_record/migration.rb:377:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:88:in `__run_callbacks__'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:778:in `_run_call_callbacks'
 - activesupport (4.2.7) lib/active_support/callbacks.rb:81:in `run_callbacks'
 - actionpack (4.2.7) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/reloader.rb:73:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
 - railties (4.2.7) lib/rails/rack/logger.rb:38:in `call_app'
 - railties (4.2.7) lib/rails/rack/logger.rb:20:in `block in call'
 - activesupport (4.2.7) lib/active_support/tagged_logging.rb:68:in `block in tagged'
 - activesupport (4.2.7) lib/active_support/tagged_logging.rb:26:in `tagged'
 - activesupport (4.2.7) lib/active_support/tagged_logging.rb:68:in `tagged'
 - railties (4.2.7) lib/rails/rack/logger.rb:20:in `call'
 - quiet_assets (1.1.0) lib/quiet_assets.rb:27:in `call_with_quiet_assets'
 - actionpack (4.2.7) lib/action_dispatch/middleware/request_id.rb:21:in `call'
 - rack (1.6.5) lib/rack/methodoverride.rb:22:in `call'
 - rack (1.6.5) lib/rack/runtime.rb:18:in `call'
 - activesupport (4.2.7) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
 - rack (1.6.5) lib/rack/lock.rb:17:in `call'
 - actionpack (4.2.7) lib/action_dispatch/middleware/static.rb:120:in `call'
 - rack (1.6.5) lib/rack/sendfile.rb:113:in `call'
 - rack-cors (0.4.0) lib/rack/cors.rb:80:in `call'
 - railties (4.2.7) lib/rails/engine.rb:518:in `call'
 - railties (4.2.7) lib/rails/application.rb:165:in `call'
 - puma (3.6.2) lib/puma/configuration.rb:225:in `call'
 - puma (3.6.2) lib/puma/server.rb:578:in `handle_request'
 - puma (3.6.2) lib/puma/server.rb:415:in `process_client'
 - puma (3.6.2) lib/puma/server.rb:275:in `block in run'
 - puma (3.6.2) lib/puma/thread_pool.rb:116:in `block in spawn_thread'

@rzane
Copy link
Owner

rzane commented Feb 16, 2017

Okay, so when you're saying:

where.has { st_intersects(:latlon, addressable) }

That actually translates to:

func = Arel::Nodes::NamedFunction.new('st_intersects', [:latlon, addressable])
func.to_sql # Boom!

Arel doesn't know how to translate addressable into SQL. I think this only worked in Squeel by pure luck.

After reviewing RGeo, it seems they're extending Arel::Attributes::Attribute to tech it how to understand this RGeo object. So, I think the right way to write this query would be like so:

where.has { latlon.st_intersects(addressable) }

This is the same as saying:

MyModel.where MyModel.arel_table[:latlon].st_intersects(addressable)

@Siggs2000
Copy link
Author

Thanks again! I actually kept running into the same RGeo / areal error with that suggested syntax but I did find some good old, bare non-squeel or baby_squeel (but horribly ugly) syntax that does work. For the moment, I'm back making forward progress! But for future seekers, maybe we can crack the case of baby_squeel equivalent syntax of this working code. Or perhaps this might actually even be an RGeo issue...

where('ST_Intersects(listings.latlon, ?)', addressable)

@rzane
Copy link
Owner

rzane commented Feb 16, 2017

How can I get an instance of whatever addressable is? Can you work up an actual test for me to try out? I'm happy to help, but I don't have enough information, and I don't know anything about RGeo.

@Schwad
Copy link

Schwad commented Feb 22, 2017

@Siggs2000 - you've probably already gone through this, but when I first did a big ol' migration on a 7,000 commit application from squeel to baby_squeel I got a lot of help from the wiki that @rzane put together. https://github.com/rzane/baby_squeel/wiki/Migrating-from-Squeel

If that doesn't help, please do add to the wiki once you've found resolution!

@nhep
Copy link

nhep commented Dec 20, 2018

I have a very similar problem, in squeel this worked:
PlanArea.where{ST_Intersects(perth_boundary, boundary)}
I converted it to:
PlanArea.where.has{ST_Intersects(perth_boundary, boundary)}
And it throws:

Minitest::UnexpectedError: Arel::Visitors::UnsupportedVisitError: Unsupported argument type: RGeo::Geos::FFIPolygonImpl. Construct an Arel node instead.
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:735:in `unsupported'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:801:in `block in inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:427:in `visit_Arel_Nodes_NamedFunction'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:403:in `visit_Arel_Nodes_Grouping'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:799:in `block in inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:616:in `visit_Arel_Nodes_And'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:248:in `block in collect_nodes_for'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `collect_nodes_for'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:232:in `visit_Arel_Nodes_SelectCore'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:195:in `block in visit_Arel_Nodes_SelectStatement'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `visit_Arel_Nodes_SelectStatement'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:8:in `accept'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb:8:in `accept'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:12:in `to_sql'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:33:in `select_all'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/query_cache.rb:97:in `select_all'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/querying.rb:39:in `find_by_sql'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:678:in `exec_queries'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:546:in `load'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:255:in `records'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:251:in `to_a'

So I tried your suggestion @rzane
PlanArea.where.has{boundary.st_intersects(perth_boundary)}.to_a
and I think it is a step forward as it calls the postgis adaptor but still throws:

Minitest::UnexpectedError: Arel::Visitors::UnsupportedVisitError: Unsupported argument type: RGeo::Geos::FFIPolygonImpl. Construct an Arel node instead.
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:735:in `unsupported'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:799:in `block in inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:817:in `aggregate'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-postgis-adapter-5.2.2/lib/active_record/connection_adapters/postgis/arel_tosql.rb:28:in `visit_RGeo_ActiveRecord_SpatialNamedFunction'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:403:in `visit_Arel_Nodes_Grouping'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:799:in `block in inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:797:in `inject_join'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:616:in `visit_Arel_Nodes_And'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:248:in `block in collect_nodes_for'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `each_with_index'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:247:in `collect_nodes_for'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:232:in `visit_Arel_Nodes_SelectCore'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:195:in `block in visit_Arel_Nodes_SelectStatement'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `each'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `inject'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/to_sql.rb:194:in `visit_Arel_Nodes_SelectStatement'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:14:in `visit'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/arel-8.0.0/lib/arel/visitors/reduce.rb:8:in `accept'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb:8:in `accept'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:12:in `to_sql'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:33:in `select_all'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/connection_adapters/abstract/query_cache.rb:97:in `select_all'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/querying.rb:39:in `find_by_sql'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:678:in `exec_queries'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:546:in `load'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:255:in `records'
    /Users/neil.hepworth/.rvm/gems/ruby-2.5.3/gems/activerecord-5.1.6.1/lib/active_record/relation.rb:251:in `to_a'

@rzane rzane closed this as completed Dec 20, 2018
@nhep
Copy link

nhep commented Dec 21, 2018

I eventually worked out that I could use baby_squeel if I did this:

# HACK! HACK! HACK!
# Monkey patch the RGeo::ActiveRecord::SpatialToSql handle to handle RGeo multipolygons
# and polygons passed as params to 'ST_Xxx' PostGIS functions
module RGeo
  module ActiveRecord
    # Arel visitor hack for spatial RGeo visitor.
    module SpatialToSql
      Arel::Visitors::Visitor.class_eval do
        def visit_RGeo_Geos_FFIPolygonImpl(node, collector)
          poly_or_muilti_toewkt(node, collector)
        end

        def visit_RGeo_Geos_FFIMultiPolygonImpl(node, collector)
          poly_or_muilti_toewkt(node, collector)
        end
      end

      private

      def poly_or_muilti_toewkt(poly_or_muilti, collector)
        boundary_as_geom = RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true)
                               .generate(poly_or_muilti)
        collector << "ST_GeomFromEWKT('#{boundary_as_geom}')"
      end
    end
  end
end

So I think this is a rgeo-activerecord issue not baby_squeel. Which is why this issue is closed I guess!

@rzane rzane reopened this Dec 21, 2018
@rzane
Copy link
Owner

rzane commented Dec 21, 2018

Yeah, sorry for closing. I don't think this is a baby squeel issue, but it would be cool to get it working. It seems like it should be doable 🤷‍♂️ . I personally don't use RGeo though, so I won't be of much help.

If someone figures out a nice, clean solution, it would be cool to add it to the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants