private method `gsub' called for 21870:Fixnum #190

Closed
rutgerg opened this Issue Jan 24, 2013 · 23 comments

Projects

None yet

6 participants

@rutgerg
rutgerg commented Jan 24, 2013

I have a search field for a Ransack: <%= f.text_field :infostrada_cont %> . Searching using this field with eg 21870 gives me and err: private method `gsub' called for 21870:Fixnum. Changing the search field to <%= f.text_field :infostrada_eq %> works but of course only for 100% matches. It is an integer field. Searching in string type field with _cont works fine. Anybody any idea what could cause this?

@radar
Member
radar commented Jan 29, 2013

Please provide a stacktrace for this error, and the version of Ransack that you're using.

@ernie
Member
ernie commented Jan 31, 2013

@radar I'm not a huge fan of the escape_wildcards impl that was added recently (or at least its placement in the Constants module). Looks like it's the culprit. I'm under water at the moment for day job stuff but the quick fix is:

    def escape_wildcards(unescaped)
      unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1')
    end
@KevinSjoberg

@ernie I completely agree with you. It's misplaced. I recently did an pull request (see #191) to update this method, but didn't want to move it without consulting with the maintainers first.

An idea would be to move this to a more reasonable location such as ransack/predicate_formatters/escape_wildcards.rb. Predicate formatters could then be required as needed for the derived predicates.

@rutgerg
rutgerg commented Feb 1, 2013

Radar,

Does this help?

ransack (0.7.2) lib/ransack/constants.rb:26:in `escape_wildcards'
ransack (0.7.2) lib/ransack/constants.rb:9
ransack (0.7.2) lib/ransack/predicate.rb:59:in `call'
ransack (0.7.2) lib/ransack/predicate.rb:59:in `format'
ransack (0.7.2) lib/ransack/nodes/condition.rb:193:in `formatted_values_for_attribute'
ransack (0.7.2) lib/ransack/nodes/condition.rb:191:in `map'
ransack (0.7.2) lib/ransack/nodes/condition.rb:191:in `formatted_values_for_attribute'
ransack (0.7.2) lib/ransack/nodes/condition.rb:167:in `arel_predicate'
ransack (0.7.2) lib/ransack/nodes/condition.rb:166:in `map'
ransack (0.7.2) lib/ransack/nodes/condition.rb:166:in `arel_predicate'
ransack (0.7.2) lib/ransack/visitor.rb:17:in `visit_Ransack_Nodes_Condition'
ransack (0.7.2) lib/ransack/visitor.rb:60:in `send'
ransack (0.7.2) lib/ransack/visitor.rb:60:in `visit'
ransack (0.7.2) lib/ransack/visitor.rb:5:in `accept'
ransack (0.7.2) lib/ransack/visitor.rb:25:in `visit_and'
ransack (0.7.2) lib/ransack/visitor.rb:25:in `map'
ransack (0.7.2) lib/ransack/visitor.rb:25:in `visit_and'
ransack (0.7.2) lib/ransack/visitor.rb:21:in `visit_Ransack_Nodes_Grouping'
ransack (0.7.2) lib/ransack/visitor.rb:60:in `send'
ransack (0.7.2) lib/ransack/visitor.rb:60:in `visit'
ransack (0.7.2) lib/ransack/visitor.rb:5:in `accept'
ransack (0.7.2) lib/ransack/adapters/active_record/context.rb:30:in `evaluate'
ransack (0.7.2) lib/ransack/search.rb:25:in `result'
app/controllers/companies_controller.rb:7:in `index'
actionpack (3.2.11) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.2.11) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.2.11) lib/abstract_controller/base.rb:167:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (3.2.11) lib/abstract_controller/callbacks.rb:18:in `process_action'
activesupport (3.2.11) lib/active_support/callbacks.rb:469:in `_run__59419566__process_action__1790286857__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `send'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `send'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.11) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in `instrument'
activesupport (3.2.11) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (3.2.11) lib/active_support/notifications.rb:123:in `instrument'
actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.2.11) lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
activerecord (3.2.11) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (3.2.11) lib/abstract_controller/base.rb:121:in `process'
actionpack (3.2.11) lib/abstract_controller/rendering.rb:45:in `process'
actionpack (3.2.11) lib/action_controller/metal.rb:203:in `dispatch'
actionpack (3.2.11) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.2.11) lib/action_controller/metal.rb:246:in `action'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `call'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:36:in `call'
journey (1.0.4) lib/journey/router.rb:68:in `call'
journey (1.0.4) lib/journey/router.rb:56:in `each'
journey (1.0.4) lib/journey/router.rb:56:in `call'
actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:601:in `call'
meta_request (0.2.1) lib/meta_request/middlewares/app_request_handler.rb:11:in `call'
rack-contrib (1.1.0) lib/rack/contrib/response_headers.rb:17:in `call'
meta_request (0.2.1) lib/meta_request/middlewares/headers.rb:16:in `call'
meta_request (0.2.1) lib/meta_request/middlewares/meta_request_handler.rb:13:in `call'
bullet (4.3.0) lib/bullet/rack.rb:11:in `call'
warden (1.2.1) lib/warden/manager.rb:35:in `call'
warden (1.2.1) lib/warden/manager.rb:34:in `catch'
warden (1.2.1) lib/warden/manager.rb:34:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.4) lib/rack/etag.rb:23:in `call'
rack (1.4.4) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.4) lib/rack/session/abstract/id.rb:210:in `context'
rack (1.4.4) lib/rack/session/abstract/id.rb:205:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/cookies.rb:341:in `call'
activerecord (3.2.11) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.11) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:28:in `call'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `_run__2131539887__call__4__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `send'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `send'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.11) lib/rails/rack/logger.rb:32:in `call_app'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `call'
activesupport (3.2.11) lib/active_support/tagged_logging.rb:22:in `tagged'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.4) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.4) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.4.4) lib/rack/lock.rb:15:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:in `call'
railties (3.2.11) lib/rails/engine.rb:479:in `call'
railties (3.2.11) lib/rails/application.rb:223:in `call'
rack (1.4.4) lib/rack/content_length.rb:14:in `call'
railties (3.2.11) lib/rails/rack/log_tailer.rb:17:in `call'
rack (1.4.4) lib/rack/handler/webrick.rb:59:in `service'
/Users/rutgergeelen/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/Users/rutgergeelen/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/Users/rutgergeelen/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/Users/rutgergeelen/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/1.8/webrick/server.rb:162:in `start'
/Users/rutgergeelen/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/1.8/webrick/server.rb:162
@KevinSjoberg

@rutgerg, @radar as @ernie pointed out, the culprit is Radar::Constants.escape_wildcards. This can be confirmed by the stack trace as well.

ransack (0.7.2) lib/ransack/constants.rb:26:in escape_wildcards'
@radar
Member
radar commented Feb 3, 2013

@KevinSjoberg: Do you have steps to reproduce this issue?

@Flauschbaellchen

I opened an issue two days ago (#195)
Somehow I did not see this one.
It's a duplicate but there you have a way to reproduce this kind of bug. rutgerg mentioned it in his first post but maybe it was not so clear.

@radar radar closed this Feb 6, 2013
@radar
Member
radar commented Feb 6, 2013

I've pushed a new release (0.7.3) which fixes this issue.

@sftsang
sftsang commented Feb 6, 2013

I just ran into this original issue right when you merged the pulled the pull request. I just updated to 0.7.3 and I ran into this new (related?) issue:

ActiveRecord::StatementInvalid: PG::Error: ERROR: operator does not exist: integer ~~* integer LINE 1: ...KE '%Reese%' AND "crop_inspections"."customer_id" ILIKE 0)) ... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

Does this belong here?

@radar
Member
radar commented Feb 6, 2013

@sftsang: yes I think it belongs here. Do you have an app you can share which reproduces this error?

@sftsang
sftsang commented Feb 6, 2013

Where this occurred is on my local dev server so I don't have an app that I can share at this moment. Just seems like it is choking on doing an ILIKE on an integer field (I don't think you can do that in Postgres without an explicit cast).

@sftsang
sftsang commented Feb 7, 2013

Not sure if this is what you wanted, but here is something I threw together to reproduce the error: https://github.com/sftsang/ransack-test

@radar radar reopened this Feb 7, 2013
@radar
Member
radar commented Feb 7, 2013

Thank you. I have just yanked 0.7.3 from RubyGems.org. I will take a look at your app before my end of day.

@radar
Member
radar commented Feb 7, 2013

I tried taking a look at this tonight, but can't come up with a clean solution. Can @KevinSjoberg or @ernie take a look and see if they fare better?

@KevinSjoberg

I'll take a look at it.

@KevinSjoberg

@radar, @sftsang this does not seem to be related to Ransack::Constants.escape_wildcards. I think this deserve it's own issue.

The reason this is failing is due to how PostgreSQL handles LIKE and ILIKE. To quote the documentation.

string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]

In @sftsang's query "crop_inspections"."customer_id" is a integer column, and integers is not supported.

What are you trying to accomplish @sftsang? By looking at your query, it seems that you want the eq predicate instead of cont.

@radar what databases does Ransack officially support? This is very specific to PostgreSQL.

@ernie
Member
ernie commented Feb 7, 2013

@KevinSjoberg Ransack supports any DB that AR does.

As for the issue, if you're using matches predicate, you will get a LIKE/ILIKE and that isn't going to work anywhere, since ARel is going to typecast the value to an int, which is what you see here.

IMHO this isn't something Ransack (nor ARel) should be accounting for, and @radar's previously-merged PR and 0.7.3 release was fine.

Use a ransacker to cast the column to string if you must have a substring search against an int.

@KevinSjoberg

@ernie agreed.

@Flauschbaellchen

As stated in the other referenced issue, the same pops up if building fully dynamic searches. (#195)
An user can combine an initially int column with predicates like contains which are only working for string columns and vice versa.
How to make it possible to create something like a before_filter so that incompatible search queries are ignored?

@sftsang
sftsang commented Feb 7, 2013

Yea, while I didn't fully understand the issues talked about in this issue, I had a feeling that this issue was only tangentially related to the original error.

Use a ransacker to cast the column to string if you must have a substring search against an int.

I realize that this isn't a support thread, but I'm obviously not the first person to try or want this. How exactly would I do what you mention?

@rutgerg
rutgerg commented Feb 8, 2013

Thanks for all the help. So with the update to 0.7.3 the error is gone but the id_cont still doesn't do what I expect it to do. Here is console output:

Started GET "/companies?utf8=%E2%9C%93&q%5Bname_cont%5D=&q%5Bid_cont%5D=2143&q%5Blistings_index_name_cont%5D=&commit=Search" for 127.0.0.1 at Thu Feb 07 23:29:15 +0100 2013
Processing by CompaniesController#index as HTML
  Parameters: {"utf8"=>"✓", "q"=>{"id_cont"=>"2143", "name_cont"=>"", "listings_index_name_cont"=>""}, "commit"=>"Search"}

Company Load (18.7ms)  SELECT DISTINCT `companies`.* FROM `companies` LEFT OUTER JOIN `listings` ON `listings`.`company_id` = `companies`.`id` LEFT OUTER JOIN `indices` ON `indices`.`id` = `listings`.`index_id` WHERE `companies`.`id` LIKE 0 ORDER BY name LIMIT 50 OFFSET 0

The cont_id 2143 is converted to LIKE 0 in the SQL statement. Is it the late hour here or is still something not quite right?

@sftsang
sftsang commented Feb 8, 2013

@rutgerg you can refer to @ernie most recent comment to answer your question. Doing a "match" (id_cont) on an integer is not supposed to work. The only way to search for an id is to do an "equal" (id_eq) in which case it won't do a partial match.

@rutgerg
rutgerg commented Feb 11, 2013

OK.Txs for all the help

@rutgerg rutgerg closed this Feb 11, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment