Rails 5中Ransack配合Simple Form实现指定字段OR分组查询
Ransack配合Simple Form实现部分字段OR分组查询的解决方法
问题根源
Simple Form的f.input/f.input_field方法会默认尝试读取绑定对象(也就是你的@q Ransack搜索实例)的同名属性,而grouping_fields是Ransack给表单构建器扩展的方法,不属于搜索实例的属性,因此套在f.input里调用会触发属性不存在的报错,直接调用表单对象的grouping_fields方法即可,不需要走Simple Form的属性渲染逻辑。
解决步骤
1. 控制器侧初始化OR分组
在你初始化@q的动作中提前构建一个OR逻辑的分组,避免首次加载页面无查询参数时,视图找不到分组对象:
# 你的控制器对应动作 def your_action @q = JobAd.ransack(params[:q]) # 仅当没有传入分组参数时初始化默认OR分组 @q.groupings.new(combinator: 'or') unless @q.groupings.any? @job_ads = @q.result(distinct: true) # 其他原有逻辑 end
2. 视图侧修改表单结构
替换原来三个布尔字段的代码段,直接调用表单对象的grouping_fields方法,块内的分组表单对象可以正常使用Simple Form的input方法:
= search_form_for @q, url: backoffice_person_offer_suggestions_path(@person), remote: true, wrapper: :default20, builder: SimpleForm::FormBuilder, html: { method: :get } do |f| = f.input :category_id_in, as: :select, collection: -> { Category.all },label: 'Category', input_html: { class: 'ld-select-button', multiple: true } = f.input :experience_min_eq, collection: ProfileForm::EXPERIENCE_YEARS, label: 'Minimum Experience Years', input_html: { class: 'ld-select-button' }, include_blank: 'Any' / [...其他字段..] / 替换原有三个布尔字段的部分,直接调用grouping_fields,不需要套f.input = f.grouping_fields @q.groupings.first do |g| = g.input :onsite_job_true, as: :ld_boolean, label: 'Onsite', input_html: { include_hidden: false } = g.input :full_remote_true, as: :ld_boolean, label: 'Fully remote', input_html: { include_hidden: false } = g.input :partial_remote_true, as: :ld_boolean, label: 'Partially remote', input_html: { include_hidden: false } / 可省略,控制器初始化时已经指定了combinator为or / = g.hidden_field :combinator, value: 'or' / [...其他字段..] = f.submit value: 'Search', class:'ld-button ld-blue-button ld-medium-button'
效果验证
修改后生成的表单字段名格式为q[g][0][onsite_job_true],Ransack会自动将g参数下的分组内条件用OR拼接,分组外的其他查询条件保持默认的AND逻辑,完全符合需求。
内容的提问来源于stack exchange,提问作者jmschp
相关产品推荐
相关产品推荐

