我正在尝试使用ransacker方法将我的一个字段从整数转换为字符串,其中包含以下内容
ransacker :invoice_no do
Arel.sql("to_char(invoice_no, '9999999')")
end
我正在使用PostgeSQL 9.1,我已经测试过在psql中手动执行,如下所示
select to_char(invoice_no, '9999999') AS invoice_no from invoices;
尝试搜索ransack时遇到的错误:invoice_no_cont
Invoice Load (1.3ms) SELECT "invoices".* FROM "invoices" WHERE "invoices"."ledger_id" = 2 AND (to_char(invoice_no, '9999999') ILIKE 0) ORDER BY invoice_no desc LIMIT 10 OFFSET 0
PG::UndefinedFunction: ERROR: operator does not exist: text ~~* integer
LINE 1: ...edger_id" = 2 AND (to_char(invoice_no, '9999999') ILIKE 0) O...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "invoices".* FROM "invoices" WHERE "invoices"."ledger_id" = 2 AND (to_char(invoice_no, '9999999') ILIKE 0) ORDER BY invoice_no desc LIMIT 10 OFFSET 0
Rendered invoices/index.json.rabl (3.6ms)
Completed 500 Internal Server Error in 12.3ms
ActiveRecord::StatementInvalid - PG::UndefinedFunction: ERROR: operator does not exist: text ~~* integer
LINE 1: ...edger_id" = 2 AND (to_char(invoice_no, '9999999') ILIKE 0) O...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "invoices".* FROM "invoices" WHERE "invoices"."ledger_id" = 2 AND (to_char(invoice_no, '9999999') ILIKE 0) ORDER BY invoice_no desc LIMIT 10 OFFSET 0:
activerecord (3.2.17) lib/active_record/connection_adapters/abstract_adapter.rb:285:in `rescue in log'
activerecord (3.2.17) lib/active_record/connection_adapters/abstract_adapter.rb:280:in `log'
activerecord (3.2.17) lib/active_record/connection_adapters/postgresql_adapter.rb:659:in `exec_query'
activerecord (3.2.17) lib/active_record/connection_adapters/postgresql_adapter.rb:1262:in `select'
activerecord (3.2.17) lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all'
activerecord (3.2.17) lib/active_record/connection_adapters/abstract/query_cache.rb:61:in `block in select_all'
activerecord (3.2.17) lib/active_record/connection_adapters/abstract/query_cache.rb:75:in `cache_sql'
activerecord (3.2.17) lib/active_record/connection_adapters/abstract/query_cache.rb:61:in `select_all'
activerecord (3.2.17) lib/active_record/querying.rb:38:in `block in find_by_sql'
更新
我在AngularJS视图中使用invoice_no_cont,就像这样。
<td data-title="'Invoice No.'" sortable="'invoice_no'" filter="{'invoice_no_cont':'text'}">
{{invoice.invoice_no}}
</td>
这是通过'GET'请求传递给Ruby on Rails服务器invoice #index方法,然后将其选中并通过ransack发送。
@invoices = Invoice.search(params[:filter]).result
答案 0 :(得分:1)
以下是我对您的问题的解释:
您忘记的是,当您将JSON数据发送回Rails服务器时,它会解析JSON有效负载。尽管您认为自己正在返回一个字符串,但json gem会解析该值并按gem's parser documentation中所述查看整数。
这意味着即使您认为自己获得了一个字符串,params哈希实际上也会将整数作为过滤键的值得到,这就是:
operator does not exist: text ~~* integer
抱怨。 Postgres希望与字符串进行比较,而不是整数。
简单的解决方法是将to_s添加到控制器中的params [:filter]。
@invoices = Invoice.search(params[:filter].to_s).result
通过这种方式,您可以确保始终将字符串组合在一起。对于您作为过滤器发送的输入,它也是一种容错的好方法。
你也不能在你的控制器中使用ransacker并做类似的事情,它可能更符合发票号码的实际性质,但更丑陋。
@invoices = params[:filter].is_a?(Integer) ? Invoice.search(params[:filter]).result : []
希望这可以解决您的问题。