2016-07-16 10 views
1

私はransack gemをレールアプリケーションで検索しています。私はemail_idsの配列をUserテーブルで検索する必要があります。 ransackingでthis問題を参照ransack gemでアレイを検索するには?

は、私が段階を追って、私はこのように行う場合には、レールコンソールで初期化子フォルダransack.rb

Ransack.configure do |config| 
    { 
    contained_within_array: :contained_within, 
    contained_within_or_equals_array: :contained_within_or_equals, 
    contains_array: :contains, 
    contains_or_equals_array: :contains_or_equals, 
    overlap_array: :overlap 
    }.each do |rp, ap| 
    config.add_predicate rp, arel_predicate: ap, wants_array: true 
    end 
end 

にこれを追加しました:

a = User.search(email_contains_array: ['[email protected]']) 

は、それが生成しますこのようなSQL:

"SELECT \"users\".* FROM \"users\" WHERE \"users\".\"deleted_at\" IS NULL AND (\"users\".\"email\" >> '---\n- [email protected]\n')" 

このようなrror:期待

User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND ("users"."email" >> '--- 
- [email protected] 
') 
ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: operator does not exist: character varying >> unknown 
LINE 1: ...RE "users"."deleted_at" IS NULL AND ("users"."email" >> '--- 
                  ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
: SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND ("users"."email" >> '--- 
- [email protected] 
') 

は、このクエリです:私は

SELECT "users".* FROM "users" WHERE ("users"."roles" @> '{"3","4"}') 

何が間違っているのでしょうか?

答えて

0

私はあなたと同じ問題に遭遇しました。私はRailsの5を使用している、と私はあなたがすでにgemfileでpostgres_ext gemを追加しているようですが、あなたはRailsの5アプリケーションでそれを使用している場合、それはいくつかの問題を抱えているUserテーブル

rolesの配列を検索する必要があります。

だから、あなたが代わりにpostgres_ext gem

を使用してのことは自分でARELノードでcontainクエリを追加するために選択されていて、Railsの他のバージョンを使用している場合、私はそれがあまりにもよくうまくいくと思います。

私はUserモデルと配列属性rolesを持っています。私がしたいのはransackを使ってrolesを検索することです。あなたと同じ条件です。

ransackアレイを検索できません。 しかしPostgresSQLは次のように配列を検索することができます:Arel Nodes

SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND (roles @> '{admin}') 

それでは、私がやりたいことは似て追加することで、クエリ含まれています

User.where("roles @> ?", '{admin}').to_sql)

それは、このようなSQLクエリを生成します

できますthis way

# app/config/initializers/arel.rb 

require 'arel/nodes/binary' 
require 'arel/predications' 
require 'arel/visitors/postgresql' 

module Arel 
    class Nodes::ContainsArray < Arel::Nodes::Binary 
    def operator 
     :"@>" 
    end 
    end 

    class Visitors::PostgreSQL 
    private 

    def visit_Arel_Nodes_ContainsArray(o, collector) 
     infix_value o, collector, ' @> ' 
    end 
    end 

    module Predications 
    def contains(other) 
     Nodes::ContainsArray.new self, Nodes.build_quoted(other, self) 
    end 
    end 
end 
1カスタム述語を掻き回すことができますので

、 のでthisようcontains掻き回す述語を追加します。

# app/config/initializers/ransack.rb 

Ransack.configure do |config| 
    config.add_predicate 'contains', 
    arel_predicate: 'contains', 
    formatter: proc { |v| "{#{v}}" }, 
    validator: proc { |v| v.present? }, 
    type: :string 
end 

を完了を!

さて、あなたは、配列を検索することができます。

User.ransack(roles_contains: 'admin') 

SQLクエリは次のようになります。

SELECT \"users\".* FROM \"users\" WHERE \"users\".\"deleted_at\" IS NULL AND (\"users\".\"roles\" @> '{[\"admin\"]}') 

うん!

関連する問題