我正试图在new rails 5 API application上设置设计。当我尝试登录时(向/v1/sign_in
发送带有POST请求的正确电子邮件和密码)我收到以下错误:
NameError (undefined local variable or method `flash' for #<SessionsController:0x007fa0f14fd280>):
devise (4.2.0) app/controllers/devise_controller.rb:157:in `set_flash_message'
devise (4.2.0) app/controllers/devise_controller.rb:164:in `set_flash_message!'
devise (4.2.0) app/controllers/devise/sessions_controller.rb:18:in `create'
actionpack (5.0.0) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.0) lib/abstract_controller/base.rb:188:in `process_action'
actionpack (5.0.0) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (5.0.0) lib/active_support/callbacks.rb:126:in `call'
activesupport (5.0.0) lib/active_support/callbacks.rb:506:in `block (2 levels) in compile'
activesupport (5.0.0) lib/active_support/callbacks.rb:455:in `call'
activesupport (5.0.0) lib/active_support/callbacks.rb:101:in `__run_callbacks__'
activesupport (5.0.0) lib/active_support/callbacks.rb:750:in `_run_process_action_callbacks'
activesupport (5.0.0) lib/active_support/callbacks.rb:90:in `run_callbacks'
actionpack (5.0.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.0.0) lib/action_controller/metal/rescue.rb:20:in `process_action'
actionpack (5.0.0) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.0.0) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (5.0.0) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.0.0) lib/active_support/notifications.rb:164:in `instrument'
actionpack (5.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.0.0) lib/action_controller/metal/params_wrapper.rb:248:in `process_action'
activerecord (5.0.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (5.0.0) lib/abstract_controller/base.rb:126:in `process'
actionpack (5.0.0) lib/action_controller/metal.rb:190:in `dispatch'
actionpack (5.0.0) lib/action_controller/metal.rb:262:in `dispatch'
actionpack (5.0.0) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack (5.0.0) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (5.0.0) lib/action_dispatch/routing/mapper.rb:16:in `block in <class:Constraints>'
actionpack (5.0.0) lib/action_dispatch/routing/mapper.rb:46:in `serve'
actionpack (5.0.0) lib/action_dispatch/journey/router.rb:39:in `block in serve'
actionpack (5.0.0) lib/action_dispatch/journey/router.rb:26:in `each'
actionpack (5.0.0) lib/action_dispatch/journey/router.rb:26:in `serve'
actionpack (5.0.0) lib/action_dispatch/routing/route_set.rb:725:in `call'
bullet (5.2.0) lib/bullet/rack.rb:12:in `call'
warden (1.2.6) lib/warden/manager.rb:35:in `block in call'
warden (1.2.6) lib/warden/manager.rb:34:in `catch'
warden (1.2.6) lib/warden/manager.rb:34:in `call'
rack (2.0.1) lib/rack/etag.rb:25:in `call'
rack (2.0.1) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.1) lib/rack/head.rb:12:in `call'
activerecord (5.0.0) lib/active_record/migration.rb:552:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/callbacks.rb:38:in `block in call'
activesupport (5.0.0) lib/active_support/callbacks.rb:97:in `__run_callbacks__'
activesupport (5.0.0) lib/active_support/callbacks.rb:750:in `_run_call_callbacks'
activesupport (5.0.0) lib/active_support/callbacks.rb:90:in `run_callbacks'
actionpack (5.0.0) lib/action_dispatch/middleware/callbacks.rb:36:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:49:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.0.0) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.0.0) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.0.0) lib/active_support/tagged_logging.rb:70:in `block in tagged'
activesupport (5.0.0) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.0.0) lib/active_support/tagged_logging.rb:70:in `tagged'
railties (5.0.0) lib/rails/rack/logger.rb:24:in `call'
request_store (1.3.1) lib/request_store/middleware.rb:9:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/request_id.rb:24:in `call'
rack (2.0.1) lib/rack/runtime.rb:22:in `call'
activesupport (5.0.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.0) lib/action_dispatch/middleware/static.rb:136:in `call'
rack (2.0.1) lib/rack/sendfile.rb:111:in `call'
rack-cors (0.4.0) lib/rack/cors.rb:80:in `call'
railties (5.0.0) lib/rails/engine.rb:522:in `call'
puma (3.6.0) lib/puma/configuration.rb:225:in `call'
puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
puma (3.6.0) lib/puma/server.rb:415:in `process_client'
puma (3.6.0) lib/puma/server.rb:275:in `block in run'
puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'
我已经尝试了一些修复方法,比如在这里添加flash中间件:
https://github.com/johndel/rails5-api-test/blob/master/config/application.rb#L44
。我还尝试在开头添加此代码:config.middleware.insert_before(Rack::Sendfile, ActionDispatch::Flash)
但仍然没有运气。知道为什么这不起作用吗?
如果您设置上述应用程序,播种它并尝试运行此命令,则可以重现它:
curl -X POST -F "user[email]=istoselidas@gmail.com" -F "user[password]=example" localhost:3000/v1/sign_in
更新
似乎sign_in.json
开箱即用,但password/edit.json
存在一个问题,这似乎与设计有关(它在此控制器上以不同的方式接近它)。
答案 0 :(得分:6)
添加中间件确实是必要的。您还需要在SessionsController
中加入Flash模块。模块Flash
显然隐含了对Helpers
的依赖,所以也包括它。
class SessionsController < Devise::SessionsController
include ActionController::Helpers
include ActionController::Flash
...
请注意,Devise允许其控制器继承自ApplicationController
,并且该控制器继承自ActionController::API
,这比通常的父类ActionController::Base
更轻薄。
Devise实际上知道所谓的导航格式。通常,这只是:html
(如果没有指定其他格式,它也恰好是请求的默认格式。)
如果您在请求中明确使用:json
格式,设计将非常智能,并且不会添加闪烁。
为此,您必须撤消所做的配置:您声明:json
为导航格式。唐&#39;吨。在设计初始值设定项中还原该行:
config.navigational_formats = [:json] # THIS IS BAD
然后,在您的请求中使用额外的.json
后缀,所有内容都将按预期工作:
curl -X POST -F "user[email]=istoselidas@gmail.com" -F "user[password]=example" localhost:3000/v1/sign_in.json
你也可以摆脱Flash中间件。
在设置Flash消息时,Devise的PasswordsController
似乎不尊重非导航格式。到目前为止,这可能还不错,因为没有人关心使用JSON API进行new
和edit
操作。您的规范中确保这些操作无法访问,这是完全合法的。
据我了解,这是Devise中的一个错误。让我们设计一个拉取请求来修复它! :)
您的PasswordsController
通过覆盖Devise::PasswordsController
和new
行动来专攻edit
。您仍然会收到错误的原因是有害代码位于名为before_filter
的{{1}}中。
因此,为您提供快速而干净的解决方案是添加自己的过滤器。您可以使用assert_reset_token_passed
方法。由于该方法呈现某些东西,它将阻止Devise的过滤器被执行。
使用这种方法,您也不需要再次覆盖操作方法。
json_not_found
答案 1 :(得分:1)
这是一个有效的丑陋修复:覆盖SessionController的create方法,从原始方法复制代码并删除设置flash消息的行:
SELECT
FriendlyFunctionCode,
MAX(MemberFirmId) as MemberFirmId,
MAX(FunctionLevel3Desc) as FuncationLevel3Desc
INTO #StagingTable
FROM
FirmFunction
GROUP BY
FriendlyFunctionCode