6

基本的な質問ですが、プロジェクトページwikiで明確なものを見つけることができませんでした。私は次のコードを持っています:

field = "secre"
Position.search( {:description_cont => field, :code_cont => field}).result(:distinct => true).to_sql
 => "SELECT DISTINCT `positions`.* FROM `positions`  WHERE ((`positions`.`description` LIKE '%secre%' AND `positions`.`code` LIKE 0))"

しかし、私のクエリは次のようになります。

 => "SELECT DISTINCT `positions`.* FROM `positions`  WHERE ((`positions`.`description` LIKE '%secre%' OR `positions`.`code` LIKE 0))"

どんな助けでもいただければ幸いです。前もって感謝します

4

5 に答える 5

4

次のことを試してください。

Position.search( {:description_or_code_cont => field}).result(:distinct => true).to_sql
于 2013-01-04T17:52:45.770 に答える
1

これはあなたの質問に対する正確な答えではないかもしれませんが、私は自分でランサックでOR検索を行う正しい方法をグーグルで探し、良い答えを見つけられませんでしたが、自分で問題を解決することができたので、私は思ったdソリューションを共有します。

私が取り組んでいるアプリケーションには、モデルのさまざまなフィールドCustomer(DBテーブルにリンクされているcustomers)をパラメーターとして受け取り、検索結果に一致する顧客のテーブルを一覧表示する検索ページがあります。顧客には3つの異なる電話番号フィールドがあり、検索ページには以前は番号のタイプごとに異なる検索フィールドがありました。それらを1つのフィールドにまとめて、すべての数字の中から便利に検索できるようにしたかったのです。

データベースには、次の3つのフィールド定義があります(これらのスニペットでは、一部の識別子名のみを変更しました)。

mysql> desc customers;
+--------------------------+------------------+------+-----+---------+----------------+
| Field                    | Type             | Null | Key | Default | Extra          |
+--------------------------+------------------+------+-----+---------+----------------+
...
| customer_phone_a         | varchar(50)      | YES  |     | NULL    |                |
| customer_phone_b         | varchar(50)      | YES  |     | NULL    |                |
| customer_phone_c         | varchar(50)      | YES  |     | NULL    |                |
+--------------------------+------------------+------+-----+---------+----------------+

以前は、検索ページ(ファイルapp/views/customers/index.html.erb)には次のものが含まれていました。

<%= search_form_for @search do |f| %> <!-- this is a Ransack-provided form -->
  <div class="field">
...
    <%= f.label :customer_phone_a_spaces_match_anything, "Phone number A is or contains:" %>
    <%= f.text_field :customer_phone_a_spaces_match_anything %>

    <%= f.label :customer_phone_b_spaces_match_anything, "Phone number B is or contains:" %>
    <%= f.text_field :customer_phone_b_spaces_match_anything %>

    <%= f.label :customer_phone_c_spaces_match_anything, "Phone number C is or contains:" %>
    <%= f.text_field :customer_phone_c_spaces_match_anything %>
...
  </div>

  <div class="actions">
    <%= f.submit "Search", class: "btn btn-large btn-primary" %>
  </div>

<% end %> <!-- search_form_for -->

(これは現在のポイントの横にありますが、ファイルの内容は次のconfig/initializers/ransack.rbとおりです。

Ransack.configure do |config|

  config.add_predicate 'spaces_match_anything',
  :arel_predicate => 'matches', # so we can use the SQL wildcard "%"
  # Format the incoming value: add the SQL wildcard character "%" to the beginning and the end of
  # the string, replace spaces by "%", and replace multiple occurrences of "%" by a single "%".
  :formatter => proc {|v| ("%"+v.gsub(" ", "%")+"%").squeeze("%")}

end

これは、Ransackのデフォルトなどに加えてeqcontカスタム述語spaces_match_anythingを検索に使用できることを意味します。述語はそれが言うことをします。)

とにかく、あなたがしたのと同じ例からインスピレーションを得て、私はモデルに次のランサッカーを追加しましたapp/models/customer.rb

ransacker :all_phones do |parent|
  Arel::Nodes::InfixOperation.new('||',
    Arel::Nodes::InfixOperation.new('||',
      Arel::Nodes::InfixOperation.new('||', parent.table[:customer_phone_a]||"", ' '),
                                    parent.table[:customer_phone_b]||"", ' '),
                                  parent.table[:customer_phone_c]||"")
end

最後に、検索ページの3つの電話番号検索フィールドを次のように置き換えました。

<%= f.label :customer_phone_a_or_customer_phone_b_or_customer_phone_c_cont, "Phone number is or contains:" %>
<%= f.text_field :customer_phone_a_or_customer_phone_b_or_customer_phone_c_cont %>

ユーザーがこの検索フィールドに入力する番号は、顧客の3つの番号のいずれかに一致するようになります。(ランサッカーのヌル番号に対するガードに注意してください||""。)

これは、Rubyv1.9.3およびRailsv3.2.8で動作するようにテストされています。入力パラメータは、スペースが正しい場所に入力されていても、検索フィールドコードにある場合でも、1つの数値の終わりと次の数値の始まりと一致しません。私は。に置き換え_contます_spaces_match_anything

于 2012-11-20T15:46:29.503 に答える
1

これをsearch_form_forタグの下にスローします。これは、fを使用していることを前提としています。

<%= f.combinator_select %>

2つのオプションで選択を生成します。ALLまたはANY。ANYはOR句を使用します。ALLはAND句を使用します。

于 2013-12-05T21:54:01.513 に答える
1

今のところ、or-クエリをransackで非常に簡単に使用できます。

Position.ransack(description: 'secret').result.or(Position.ransack(code: 0).result)
于 2019-11-21T12:01:57.093 に答える
0

Ransackのデモコードをしばらく掘り下げた後、次のように実行しました。

field = "secre"
q= {
  "m"=>"or", 
  "c"=>{
    "0"=>{
      "a"=>{
        "0"=>{
          "name"=>"description"
        }
      }, 
      "p"=>"cont", 
      "v"=>{
        "0"=>{
          "value"=>field
        }
      }
    }, 
    "1"=>{
      "a"=>{
        "0"=>{
          "name"=>"code"
        }
      }, 
      "p"=>"cont", 
      "v"=>{
        "0"=>{
          "value"=>field
        }
      }
    }
  }
}
Position.search(q).result(:distinct => true).to_sql
 => "SELECT DISTINCT `positions`.* FROM `positions`  WHERE ((`positions`.`description` LIKE '%secre%' OR `positions`.`code` LIKE 0))"

ええ、それはひどいです、そして確かにそれはそれをするための最良の方法ではないはずです、しかしそれは私を一時的に救いました。他に何か考えはありますか?

于 2012-10-17T20:09:38.250 に答える