【问题标题】:Rails gem Ransack -> search 'or condition' with 'is null' and a specific value (field=x OR field IS NULL)Rails gem Ransack -> 使用“is null”和特定值(field=x OR field IS NULL)搜索“或条件”
【发布时间】:2013-10-18 10:47:01
【问题描述】:

我为我们的支持者制作了一个支持票证系统 - 使用 ruby​​ on rails (Ruby 1.9.3 Rails 3.2) 进行编程

有一个与用户(支持者)关联belongs_to 的票证模型。

我使用 Ernie 的宝石 Ransack 进行搜索。 当支持者搜索他自己的门票(由tickets_controller.index 处理)时,他还应该在搜索结果(views/tickets/index)中看到未关联的门票(结合其他搜索条件,例如“日期”或其他)

(这样他就可以拿一张未开票)

预期的 SQL 语句:

SELECT * FROM tickets WHERE ... AND (user_id=5 OR user_id IS NULL) AND ... 

我在索引视图的搜索表单中尝试了user_id_null_or_user_id_eq - 但这不起作用(没有方法错误)

如何制作自定义谓词(或 ransacker)来解决此问题? (感谢@Magnuss 的评论)

很遗憾,我没有使用 Arel 的经验

类似:

ransacker :user_null_or_eq do
    ...
end

在门票模型中。

我希望这能更详细地解释问题。

感谢您的帮助。

【问题讨论】:

  • 您似乎没有提供足够的信息来提供帮助。
  • 看来 Ransack 不会让你做null_or 查询。您必须创建自己的谓词(ransacker ?)。
  • @Beerlington - 我试图更详细地解释这个问题

标签: ruby-on-rails arel ransack


【解决方案1】:

我也必须弄清楚这一点,@TomG 的回答很有帮助! 你真的不需要为这个问题创建一个 ransacker,它可以通过使用 ransack 的 build_grouping 方法来修复(在任何地方都没有记录......)并将你需要的条件放入 'or' 条件。

我用它来搜索要添加到笼子中的项目,但想只向用户显示我的笼子中还没有的项目(也没有分配给任何其他笼子),所以在我的控制器中:

   @search = Cage.ransack(params[:q])
   @search.build_grouping({:m => 'or', :storage_id_not_eq => @cage_item.id, :storage_id_null => true})  
   @results_count = @search.result(:distinct => true).length
   @items = @search.result(:distinct => true).paginate(:per_page => 20, :page => params[:page] || 1)

   @search.build_condition if @search.conditions.empty?
   @search.build_sort if @search.sorts.empty?

所以当我打印查询 ransack 时,它会显示:

 @search.result.to_sql
"SELECT `specimens`.* FROM `specimens`  WHERE (`specimens`.`deleted_at` IS NULL) AND ((`specimens`.`storage_id` != 183 OR `specimens`.`storage_id` IS NULL))"

如果我添加名称查询:

@search.result.to_sql
"SELECT `specimens`.* FROM `specimens`  WHERE (`specimens`.`deleted_at` IS NULL) AND ((`specimens`.`name` LIKE '%root%' AND (`specimens`.`storage_id` != 183 OR `specimens`.`storage_id` IS NULL)))"

希望这可以帮助您或其他人在使用 OR 而不是基本 AND 时遇到问题。

【讨论】:

    【解决方案2】:

    好的 - 这是我自己的解决方案 - 灵感来自 graywh(非常感谢):ransack/issues/290

    您可以将带有“或”组合器的新分组节点添加到 ransack 对象。

    在索引视图中,我将f.select :user_id_eq 更改为select_tag ...

    tickets_controller.index:

    @q = Ticket.search(params[:q])  
    if params[:user_id_eq] && params[:user_id_eq]!=''  
      @q.build_grouping({:m => 'or', :user_id_eq => params[:user_id_eq], :user_id_null => true})  
    end
    

    【讨论】:

      【解决方案3】:

      你可以像这样构建你的查询参数

      q: {g: [ {m: 'or', user_id_eq: 5, user_id_null: 1} ] }
      

      这里:

      user_id_null: 1
      

      只是搜索空值的标志

      【讨论】:

        猜你喜欢
        • 2015-04-21
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        相关资源
        最近更新 更多