[英]Rails 3.2 Engine weirdness with before_filter
我有一个Rails 3.2.6应用程序,需要您登录才能使用它。 它还有一个安装在/api
上的Rails Engine,它可以为某些部分提供JSON API,而无需身份验证。
当我启动Rails服务器并提出以下请求时:
GET /api/something
GET /
GET /api/something
一切正常,API请求返回应有的JSON,主页呈现html页面。
这是奇怪的部分。 如果我在启动Rails服务器后立即按此顺序发出请求:
GET /
GET /api/something
GET /api/something
然后,API请求失败。 根Rails应用程序中的before过滤器为API引擎触发,导致重定向到UserSessionsController#new
,该重定向在API引擎中不存在,并且失败。 虽然如果先向API引擎而不是根Rails应用程序发出请求,则API引擎不会在过滤器之前继承。 这种怪异的任何光芒都将是巨大的:)
尽管我目前的计划是将API引擎变成一个完全独立的Rack应用。 目前看来,它是引擎的唯一原因是让我之前的某个人真的很喜欢引擎。
经过一番挖掘,我发现了问题。 是引擎本身。 我应该指出,我不负责该项目的创建,而只是负责与其合作。
可以说我们的主机Rails应用具有...
app/controllers/application_controller.rb
:
class ApplicationController < ActionController::Base
before_filter :foo_bar
layout :application
end
我们的引擎称为api_engine,在ApiEngine
模块下被隔离,并且具有...
app/controllers/api_engine/application_controller.rb
:
module ApiEngine
class ApplicationController < ActionController::Base
layout false
end
end
app/controllers/api_engine/post_controller.rb
:
module ApiEngine
class PostController < ApplicationController
# code goes here...
end
end
你已经知道我要去哪里了吗? 问题是Rails的动态加载和愚蠢地构造引擎的结合。
当对服务器的第一个请求是对引擎的PostController
,则需要post_controller.rb
文件,该文件在ApiEngine
模块内的ApplicationController
常量中。 但是::ApiEngine::ApplicationController
未定义,因此它检查::ApplicationController
是否被定义,而这不是,导致在引擎内寻找application_controller.rb
。
但是,如果第一个请求发送到宿主应用程序,该应用程序最终定义了ApplicationController
,那么当引擎收到请求时,它仅使用根应用程序中的ApplicationController
结束了,而不需要它自己的类版本。
该解决方案非常简单,在引擎的lib/api_engine/engine.rb
文件中,需要在config.after_initialize
块中使用正确的应用程序控制器文件:
module ApiEngine
class Engine < Rails::Engine
isolate_namespace ApiEngine
config.after_initialize do
require "api_engine/application_controller"
end
end
end
进行跟踪有点棘手,特别是在处理其他人的代码时,您倾向于假定某些“基本”功能可以正常工作。 希望如果有人发现自己处于类似怪异的情况,这个答案可能会有用:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.