我为我们的支持者制作了一个支持票系统 - 用Ruby on Rails编程(Ruby 1.9.3 Rails 3.2)
有一个与用户(支持者)具有belongs_to
关联的票证模型。
我使用厄尼的宝石Ransack进行搜索。当支持者搜索自己的票证(由tickets_controller.index处理)时,他还应该在搜索结果中看到未关联的票证(视图/票证/索引)(与其他serach条件相结合,例如。"日期"或其他内容)
(这样他就可以拿一张开票了)
预期的 SQL 语句:
SELECT * FROM tickets WHERE ... AND (user_id=5 OR user_id IS NULL) AND ...
我尝试在索引视图的搜索表单中user_id_null_or_user_id_eq
- 但这不起作用(没有方法错误)
如何制作自定义谓词(或洗劫机)来解决此问题?(感谢@Magnuss的评论)
不幸的是,我没有与阿雷尔合作的经验
像这样:
ransacker :user_null_or_eq do
...
end
在工单模型中。
我希望这能更详细地解释这个问题。
感谢您的任何帮助。
我也必须弄清楚这一点,@TomG答案有很大帮助!您真的不需要为此问题创建洗劫机,而是通过使用build_grouping的洗劫方法(在任何地方都没有记录......)来修复它,并使用"或"条件放入您需要的条件。
我用它来搜索要添加到笼子中的项目,但只想向用户显示尚未在我的笼子中的物品(也未分配给任何其他笼子),因此在我的控制器中:
@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)))"
希望这可以帮助您或其他人在洗劫条件而不是基本的 AND 中使用 OR 时遇到问题。
这是我自己的解决方案 - 灵感来自 Graywh(非常感谢):Ransack/issues/290
您可以向 ransack 对象添加一个带有"or"组合器的新分组节点。
在索引视图中,我f.select :user_id_eq
更改为select_tag ...
tickets_controller.索引:
@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
你可以像这样构建你的查询参数
q: {g: [ {m: 'or', user_id_eq: 5, user_id_null: 1} ] }
其中:
user_id_null: 1
是搜索空值的唯一标志