繁体   English   中英

使用before_filter的Rails 3.2引擎怪异

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM