如何在Ransack的sort_link中使用自定义URL及参数?
解决嵌套路由下Ransack sort_link传递自定义参数的问题
我之前在做嵌套路由+Ransack排序的时候也踩过这个坑,其实sort_link是支持传递自定义URL参数的,只是不像search_form_for那样直观,给你几个靠谱的解决思路:
1. 直接给sort_link传递url选项
sort_link方法本身就接受url参数,你只需要把嵌套路由的路径辅助方法和自定义参数一起传进去就行。举个实际例子:
假设你的嵌套路由是/projects/:project_id/tasks,并且需要传递自定义参数status,那视图里的sort_link可以这么写:
<%= sort_link @q, :due_date, "截止日期", url: project_tasks_path(@project, status: params[:status]) %>
这里把嵌套的父资源实例@project和自定义参数status(从当前请求的params里取)都放进路径辅助方法,生成的排序链接就会自动带上这些参数了。
2. 封装自定义辅助方法(适合频繁使用的场景)
如果你的项目里很多地方都需要这种带自定义参数的排序链接,不如自己封装一个辅助方法,省得每次都重复写参数。在app/helpers/application_helper.rb里添加:
def nested_sort_link(q, attribute, label = nil, **options) # 保留当前请求里的嵌套参数和自定义参数,排除掉控制器、动作这些无关参数 preserved_params = params.except(:controller, :action, :page) target_url = url_for(preserved_params) sort_link q, attribute, label, url: target_url, **options end
之后在视图里直接用这个自定义方法就行:
<%= nested_sort_link @q, :name, "任务名称" %>
它会自动带上当前请求里的所有嵌套参数和自定义参数,非常省心。
3. 确保控制器里的参数正确传递
另外要注意,在控制器的index动作里,要确保Ransack的搜索对象@q是基于包含自定义参数的查询构建的,同时强参数要允许这些自定义参数:
def index @project = Project.find(params[:project_id]) @q = @project.tasks.ransack(params[:q].merge(status: params[:status])) @tasks = @q.result(distinct: true) end private def task_params params.permit(:project_id, :status, q: [:sort, :direction, *Task.ransackable_attributes]) end
这样能保证排序时参数不会丢失,同时符合Rails的强参数规范。
内容的提问来源于stack exchange,提问作者Anonymus
相关产品推荐
相关产品推荐

