实现动态搜索表单,避免Controller代码冗余
问题描述
我有一个支持按姓名和邮箱两种方式搜索记录的表单,代码如下:
<%= form_tag(clients_path, method: :get, class: "d-flex") do %> <%= text_field_tag(:client_name, params[:client_name], placeholder: "Buscar por nombre", class: "form-control") %> <%= text_field_tag(:client_email, params[:client_email], placeholder: "Buscar por email", class: "form-control") %> <%= submit_tag ("Buscar"), class: "btn btn-primary" %> <% end %>
当前控制器代码仅支持单一条件搜索:
if params[:client_name] @clients = User.where(name: params[:name]) else @clients = User.all end if params[:client_email] @clients = User.where(email: params[:client_email]) else @clients = User.all end
请问如何让控制器代码动态化,在满足任一条件时返回对应结果,同时避免代码冗余?
解决方案
先修复基础错误
首先注意控制器里的参数匹配问题:params[:name]应该对应表单里的client_name参数,即params[:client_name],否则姓名搜索逻辑会失效。
链式拼接实现多条件动态搜索
最简洁且易维护的方式是通过链式查询拼接,既支持单一条件,也支持组合条件搜索,同时消除冗余代码:
@clients = User.all # 姓名模糊搜索(若需要精确匹配,可去掉LIKE和百分号) if params[:client_name].present? @clients = @clients.where("name LIKE ?", "%#{params[:client_name]}%") end # 邮箱搜索(同理,可选择精确或模糊匹配) if params[:client_email].present? @clients = @clients.where("email LIKE ?", "%#{params[:client_email]}%") end
精简版(精确匹配场景)
如果业务只需要精确匹配,可通过构建条件哈希的方式进一步简化代码:
search_filters = {} search_filters[:name] = params[:client_name] if params[:client_name].present? search_filters[:email] = params[:client_email] if params[:client_email].present? @clients = search_filters.present? ? User.where(search_filters) : User.all
逻辑说明
- 初始默认加载所有用户,仅当对应搜索参数存在且非空时,追加查询条件
- 链式查询会自动合并多个条件,实现"同时满足姓名+邮箱"的组合搜索
- 避免了重复的
else @clients = User.all赋值,大幅减少冗余代码
内容的提问来源于stack exchange,提问作者user3074558
相关产品推荐
相关产品推荐

