【发布时间】:2021-03-25 14:59:11
【问题描述】:
我目前正在开发一个 Rails 引擎,它将在一定范围内复制宿主应用程序的路由。因此,如果原始应用程序中存在路由get '/posts', to: 'posts#index', as: 'posts',则该路由也应在引擎安装get '/mount/posts' 下可用,但应指向主机应用程序中的相同Contoller#Action。
但是,我无法访问最终的应用程序,因此必须动态生成路由。
以下是我目前的方法,但也许以另一种方式效果更好?
# lib/embed_me.rb
require "embed_me/engine"
module EmbedMe
# defines a scoped route under which the embedded content can be found
mattr_accessor :scope_name, default: :embed
end
# lib/embed_me/engine.rb
module EmbedMe
class Engine < ::Rails::Engine
isolate_namespace EmbedMe
initializer "embed_me", before: :load_config_initializers do |app|
Rails.application.routes.append do
mount EmbedMe::Engine, at: EmbedMe.scope_name
end
end
end
end
# config/routes.rb
EmbedMe::Engine.routes.draw do
match '/*path', to: 'application#index', via: :all
end
# app/controllers/embed_me/application_controller.rb
module EmbedMe
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def index
# will validate existance of route, or raise ActionController::RoutingError
path = Rails.application.routes.recognize_path(params[:path])
controller = path[:controller]
action = path[:action]
# how to call original action?
end
end
end
我不能使用redirect_to("/#{params[:path]}"),因为它会将 URL 更改为无范围的 URL。
我不能使用render(action: action, controller: controller),因为只会渲染相应的视图,但是会跳过控制器中的逻辑。 (或者我做错了什么?)
我不能使用main_app.resource_path,因为路由不是静态的,并且因应用程序而异。
【问题讨论】:
-
这不是一条可行的前进道路。 Rails 不是为了从一个控制器到另一个控制器的内部“转发”而构建的,它会使调试变成真正的地狱。我猜你可能会做的是让你的引擎像 rails 一样读取路由文件并创建一个修改后的路由集合,然后以某种方式将其插入到主机应用程序中。这可能需要大量的工作和深入研究内部结构。我建议您先阅读medium.com/rubyinside/…。
-
谢谢。我去看看链接
标签: ruby-on-rails ruby rails-routing rails-engines