Rails命名空间下签名创建后重定向至项目详情的优化方案咨询
解决命名空间模型重定向路由缺失问题
当你重定向到处于masterdata命名空间下的Project实例时,Rails默认会尝试调用无命名空间的project_url路由助手,但你的路由都在masterdata命名空间下,因此报错。以下是几种无需新增重定向路由的替代方案:
方案1:让Project实例自己生成正确路由
通过覆盖模型的route_for方法,让Rails自动生成命名空间下的路由:
# app/models/project.rb class Project < ApplicationRecord def route_for(action = :show, options = {}) case action when :show, :edit, :update, :destroy [:masterdata, self] # 指定命名空间和实例 else super # 其他动作沿用默认逻辑 end end end
修改后,直接执行redirect_to params[:signature].signable就能自动解析为masterdata_project_path,无需改动控制器代码。
方案2:在控制器中针对性处理
在SignaturesController的create动作里,对Project类型的signable单独指定路由:
# app/controllers/signatures_controller.rb def create @signature = Signature.new(signature_params) if @signature.save signable = @signature.signable redirect_to signable.is_a?(Project) ? masterdata_project_path(signable) : signable else render :new # 处理保存失败逻辑 end end
这种方式逻辑直白,适合只有少数模型在命名空间下的场景,不会影响模型的其他行为。
方案3:用多态路由传递命名空间
利用Rails多态路由的特性,通过数组形式组合命名空间和模型实例:
# app/controllers/signatures_controller.rb def create @signature = Signature.new(signature_params) if @signature.save signable = @signature.signable redirect_path = signable.is_a?(Project) ? polymorphic_path([:masterdata, signable]) : polymorphic_path(signable) redirect_to redirect_path else render :new end end
后续如果有其他模型加入masterdata命名空间,只需扩展判断条件即可,扩展性较好。
方案4:给模型加自定义路由方法
在Project模型中定义生成命名空间路由的方法,重定向时直接调用:
# app/models/project.rb class Project < ApplicationRecord def masterdata_path Rails.application.routes.url_helpers.masterdata_project_path(self) end end
# app/controllers/signatures_controller.rb def create @signature = Signature.new(signature_params) if @signature.save signable = @signature.signable redirect_to signable.is_a?(Project) ? signable.masterdata_path : signable else render :new end end
这种方式灵活可控,你可以根据需求定义不同场景的路由方法,不会干扰模型默认的路由生成逻辑。
内容的提问来源于stack exchange,提问作者Sig
相关产品推荐
相关产品推荐

