如何在Rails中动态获取指定模型的所有路由助手及对应请求方法、动作信息
如何在Rails中动态获取指定模型的所有路由助手及对应请求方法、动作信息
我明白你想要的效果——精准获取某一个模型对应的所有路由助手信息,还得带上请求方法和动作,而不是靠模糊的字符串匹配把相似命名的模型路由也混进来。这确实得从路由的底层关联入手,下面给你一个可靠的实现方案:
实现代码
def route_helpers_for_model(model_class) # 把模型类转换成对应的控制器名称(遵循RESTful默认命名规则) controller_name = model_class.to_s.pluralize.underscore all_routes = Rails.application.routes.routes all_routes.each_with_object([]) do |route, result| # 过滤条件:必须属于目标控制器,且有命名路由助手 next unless route.defaults[:controller] == controller_name && route.name.present? # 处理请求方法,比如把"GET|HEAD"这类多方法路由提取主方法 request_method = route.verb.split('|').first # 获取该路由对应的_path和_url两种助手名称 route_helper = Rails.application.routes.named_routes[route.name] helper_names = [route_helper.path_helper, route_helper.url_helper] helper_names.each do |helper| result << { method: request_method, helper: helper, action: route.defaults[:action] } end end.uniq end
代码说明
- 精准关联模型与路由:通过模型类生成对应的控制器名称(比如
Post对应"posts"),这比单纯匹配字符串要可靠得多,完全避免了OtherPost这类相似命名模型的干扰。 - 过滤无效路由:只保留属于目标控制器且有命名助手的路由,排除掉通配路由、无命名的自定义路由等无用条目。
- 处理多方法路由:有些路由同时支持
GET和HEAD,这里提取第一个方法作为代表,你可以根据需求调整逻辑。 - 包含两种助手格式:每个命名路由都有
_path(相对路径)和_url(绝对路径)两种助手,代码里会把两者都收集进来。
使用示例
调用方法传入目标模型类即可:
route_helpers_for_model(Post)
返回的结果结构如下(示例):
[ { method: "GET", helper: "post_path", action: "show" }, { method: "GET", helper: "post_url", action: "show" }, { method: "PATCH", helper: "post_path", action: "update" }, { method: "PATCH", helper: "post_url", action: "update" }, { method: "DELETE", helper: "post_path", action: "destroy" }, { method: "GET", helper: "posts_path", action: "index" }, { method: "GET", helper: "posts_url", action: "index" }, { method: "GET", helper: "new_post_path", action: "new" }, { method: "GET", helper: "new_post_url", action: "new" }, { method: "POST", helper: "posts_path", action: "create" }, { method: "POST", helper: "posts_url", action: "create" }, { method: "GET", helper: "edit_post_path", action: "edit" }, { method: "GET", helper: "edit_post_url", action: "edit" } ]
这个方案不仅能覆盖默认的RESTful路由,如果你有自定义的命名路由只要归属目标控制器,也会被一并收集到。
备注:内容来源于stack exchange,提问作者Some Guy
相关产品推荐
相关产品推荐

