与hansack进行OR

一个基本的问题,但我在项目页面或维基中找不到清楚的东西。 我有以下代码:

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))" 

任何帮助,将不胜感激。 提前致谢

请尝试以下方法:

 Position.search( {:description_or_code_cont => field}).result(:distinct => true).to_sql 

这可能不是你的问题的确切答案,但因为我在谷歌搜索正确的方式在Ransack自己进行OR搜索,并没有找到一个好的答案,但确实设法自己解决问题,我想我’ d分享解决方案。

在我正在处理的应用程序中,有一个搜索页面,它将模型Customer的各个字段(链接到DB表customers )作为参数,然后列出与搜索结果匹配的那些客户的表。 客户具有三个不同的电话号码字段,并且搜索页面先前针对每种类型的号码具有不同的搜索字段。 我想将它们组合成一个可以方便地在所有数字中搜索的字段。

数据库有这三个字段定义(在这些片段中,我只更改了一些标识符名称):

 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| %>  
... <%= 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 %> ...
<%= f.submit "Search", class: "btn btn-large btn-primary" %>
<% end %>

(这是目前的观点,但文件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 

最后,我用搜索页面替换了三个电话号码搜索字段:

 <%= 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 %> 

用户在此搜索字段中输入的数字现在将匹配客户的三个数字中的任何一个。 (请注意在搜索引擎中防范空号码, ||"" 。)

这经测试可与Ruby v1.9.3和Rails v3.2.8一起使用。 输入参数将不匹配一个数字的结尾和下一个数字的开头,即使在正确的位置输入空格也是如此,即使在搜索字段代码中,我_cont _spaces_match_anything替换为_spaces_match_anything

把它扔在你的search_form_for标签下面。 这假设您正在使用f:

 <%= f.combinator_select %> 

它会生成一个有两个选项的选择。 全部或任何。 任何人都会使用OR条款。 ALL将使用AND子句。

在挖掘了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))" 

是的,它是严重的,并且肯定它不应该是最好的方式,但它暂时救了我。 还有其他想法吗?