将 Rails + mongoid 与嵌入式 shopify 应用集成时出现问题

Problem integrating Rails + mongoid with embedded shopify app

我正在 Rails 6.0.3.2 上构建一个嵌入式 Shopify 应用程序,并使用 mongoid gem 的最新版本来使用 MongoDB。我也在使用最新版本的 shopify_app gem.

gem 'mongoid', '7.1.4'
gem 'shopify_app', '15.0.0'

我的问题出现在尝试通过 POST 请求访问我自己的控制器之一时。在此特定实例中,它是一个 create 控制器,用于通过 Shopify::API 创建订单。 我认为该错误与嵌入式应用程序在后台进行的身份验证有关。

此错误仅在调用控制器继承自 AuthenticatedController 时发生。这是由 shopify_app gem 生成的控制器,需要进行身份验证,并且需要在嵌入式应用程序中使用 Shopify::API。如果我简单地更改为 < ApplicationController

错误消失了。这个错误发生时并没有真正尝试从控制器访问 Mongo,即使调用一个空控制器,虽然只有一个被 POST 请求访问,但通过 GET 请求访问的控制器工作正常。我什至有一个控制器在从 ApplicationController 继承时具有有效的创建操作,一旦它从 AuthenticatedController 继承就会中断。这就是为什么我认为它与 embedded_app 和商店之间的后台身份验证有关。

这个错误可以在下面看到

Mongo::Error::OperationFailure in OrderFulfillmentsController#update_orders
unknown operator: $oid (2) (on localhost:27017, modern retry, attempt 1)

Application Trace | Framework Trace | Full Trace
mongo (2.13.1) lib/mongo/operation/result.rb:321:in raise_operation_failure' mongo (2.13.1) lib/mongo/operation/result.rb:289:in validate!'
mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:29:in block (3 levels) in validate_result' mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:96:in add_server_diagnostics'
mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:28:in block (2 levels) in validate_result' mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:43:in add_error_labels'
mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:27:in block in validate_result' mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:82:in unpin_maybe'
mongo (2.13.1) lib/mongo/operation/shared/response_handling.rb:26:in validate_result' mongo (2.13.1) lib/mongo/operation/shared/executable.rb:45:in block in execute'
mongo (2.13.1) lib/mongo/operation/shared/executable.rb:44:in tap' mongo (2.13.1) lib/mongo/operation/shared/executable.rb:44:in execute'
mongo (2.13.1) lib/mongo/operation/shared/op_msg_or_find_command.rb:29:in block in execute' mongo (2.13.1) lib/mongo/server/connection_pool.rb:590:in with_connection'
mongo (2.13.1) lib/mongo/server.rb:425:in with_connection' mongo (2.13.1) lib/mongo/operation/shared/op_msg_or_find_command.rb:27:in execute'
mongo (2.13.1) lib/mongo/collection/view/iterable.rb:104:in send_initial_query' mongo (2.13.1) lib/mongo/collection/view/iterable.rb:46:in block in each'
mongo (2.13.1) lib/mongo/retryable.rb:61:in block in read_with_retry_cursor' mongo (2.13.1) lib/mongo/retryable.rb:316:in modern_read_with_retry'
mongo (2.13.1) lib/mongo/retryable.rb:117:in read_with_retry' mongo (2.13.1) lib/mongo/retryable.rb:60:in read_with_retry_cursor'
/usr/share/rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/forwardable.rb:235:in read_with_retry_cursor' mongo (2.13.1) lib/mongo/collection/view/iterable.rb:45:in each'
mongoid (7.1.4) lib/mongoid/query_cache.rb:228:in each' mongoid (7.1.4) lib/mongoid/contextual/mongo.rb:282:in first'
mongoid (7.1.4) lib/mongoid/contextual/mongo.rb:282:in find_first' /usr/share/rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/forwardable.rb:235:in find_first'
mongoid (7.1.4) lib/mongoid/findable.rb:119:in find_by' shopify_app (15.0.0) lib/shopify_app/session/shop_session_storage.rb:20:in retrieve'
shopify_app (15.0.0) lib/shopify_app/session/session_repository.rb:12:in retrieve_shop_session' shopify_app (15.0.0) lib/shopify_app/controller_concerns/login_protection.rb:76:in shop_session_by_cookie'
shopify_app (15.0.0) lib/shopify_app/controller_concerns/login_protection.rb:65:in shop_session' shopify_app (15.0.0) lib/shopify_app/controller_concerns/login_protection.rb:45:in current_shopify_session'
shopify_app (15.0.0) lib/shopify_app/controller_concerns/login_protection.rb:89:in login_again_if_different_user_or_shop' activesupport (6.0.3.4) lib/active_support/callbacks.rb:428:in block in make_lambda'
activesupport (6.0.3.4) lib/active_support/callbacks.rb:200:in block (2 levels) in halting' actionpack (6.0.3.4) lib/abstract_controller/callbacks.rb:34:in block (2 levels) in module:Callbacks'
activesupport (6.0.3.4) lib/active_support/callbacks.rb:201:in block in halting' activesupport (6.0.3.4) lib/active_support/callbacks.rb:513:in block in invoke_before'
activesupport (6.0.3.4) lib/active_support/callbacks.rb:513:in each' activesupport (6.0.3.4) lib/active_support/callbacks.rb:513:in invoke_before'
activesupport (6.0.3.4) lib/active_support/callbacks.rb:110:in block in run_callbacks' activesupport (6.0.3.4) lib/active_support/callbacks.rb:139:in run_callbacks'
actionpack (6.0.3.4) lib/abstract_controller/callbacks.rb:41:in process_action' actionpack (6.0.3.4) lib/action_controller/metal/rescue.rb:22:in process_action'
actionpack (6.0.3.4) lib/action_controller/metal/instrumentation.rb:33:in block in process_action' activesupport (6.0.3.4) lib/active_support/notifications.rb:180:in block in instrument'
activesupport (6.0.3.4) lib/active_support/notifications/instrumenter.rb:24:in instrument' activesupport (6.0.3.4) lib/active_support/notifications.rb:180:in instrument'
actionpack (6.0.3.4) lib/action_controller/metal/instrumentation.rb:32:in process_action' actionpack (6.0.3.4) lib/action_controller/metal/params_wrapper.rb:245:in process_action'
mongoid (7.1.4) lib/mongoid/railties/controller_runtime.rb:22:in process_action' actionpack (6.0.3.4) lib/abstract_controller/base.rb:136:in process'
actionview (6.0.3.4) lib/action_view/rendering.rb:39:in process' actionpack (6.0.3.4) lib/action_controller/metal.rb:190:in dispatch'
actionpack (6.0.3.4) lib/action_controller/metal.rb:254:in dispatch' actionpack (6.0.3.4) lib/action_dispatch/routing/route_set.rb:50:in dispatch'
actionpack (6.0.3.4) lib/action_dispatch/routing/route_set.rb:33:in serve' actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:49:in block in serve'
actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:32:in each' actionpack (6.0.3.4) lib/action_dispatch/journey/router.rb:32:in serve'
actionpack (6.0.3.4) lib/action_dispatch/routing/route_set.rb:834:in call' omniauth (1.9.1) lib/omniauth/strategy.rb:192:in call!'
omniauth (1.9.1) lib/omniauth/strategy.rb:169:in call' omniauth (1.9.1) lib/omniauth/builder.rb:45:in call'
rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in call' rack (2.2.3) lib/rack/etag.rb:27:in call'
rack (2.2.3) lib/rack/conditional_get.rb:40:in call' rack (2.2.3) lib/rack/head.rb:12:in call'
actionpack (6.0.3.4) lib/action_dispatch/http/content_security_policy.rb:18:in call' rack (2.2.3) lib/rack/session/abstract/id.rb:266:in context'
rack (2.2.3) lib/rack/session/abstract/id.rb:260:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/cookies.rb:648:in call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/callbacks.rb:27:in block in call' activesupport (6.0.3.4) lib/active_support/callbacks.rb:101:in run_callbacks'
actionpack (6.0.3.4) lib/action_dispatch/middleware/callbacks.rb:26:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/executor.rb:14:in call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/debug_exceptions.rb:32:in call'
web-console (4.1.0) lib/web_console/middleware.rb:132:in call_app' web-console (4.1.0) lib/web_console/middleware.rb:19:in block in call'
web-console (4.1.0) lib/web_console/middleware.rb:17:in catch' web-console (4.1.0) lib/web_console/middleware.rb:17:in call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/show_exceptions.rb:33:in call' railties (6.0.3.4) lib/rails/rack/logger.rb:37:in call_app'
railties (6.0.3.4) lib/rails/rack/logger.rb:26:in block in call' activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:80:in block in tagged'
activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:28:in tagged' activesupport (6.0.3.4) lib/active_support/tagged_logging.rb:80:in tagged'
railties (6.0.3.4) lib/rails/rack/logger.rb:26:in call' sprockets-rails (3.2.2) lib/sprockets/rails/quiet_assets.rb:13:in call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/remote_ip.rb:81:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/request_id.rb:27:in call'
rack (2.2.3) lib/rack/method_override.rb:24:in call' shopify_app (15.0.0) lib/shopify_app/middleware/jwt_middleware.rb:23:in call_next'
shopify_app (15.0.0) lib/shopify_app/middleware/jwt_middleware.rb:11:in call' shopify_app (15.0.0) lib/shopify_app/middleware/same_site_cookie_middleware.rb:11:in call'
rack (2.2.3) lib/rack/runtime.rb:22:in call' activesupport (6.0.3.4) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call'
actionpack (6.0.3.4) lib/action_dispatch/middleware/executor.rb:14:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/static.rb:126:in call'
rack (2.2.3) lib/rack/sendfile.rb:110:in call' actionpack (6.0.3.4) lib/action_dispatch/middleware/host_authorization.rb:82:in call'
webpacker (4.3.0) lib/webpacker/dev_server_proxy.rb:23:in perform_request' rack-proxy (0.6.5) lib/rack/proxy.rb:57:in call'
railties (6.0.3.4) lib/rails/engine.rb:527:in call' puma (4.3.6) lib/puma/configuration.rb:228:in call'
puma (4.3.6) lib/puma/server.rb:713:in handle_request' puma (4.3.6) lib/puma/server.rb:472:in process_client'
puma (4.3.6) lib/puma/server.rb:328:in block in run' puma (4.3.6) lib/puma/thread_pool.rb:134:in block in spawn_thread'

这可以通过在您的 Shop class 上定义以下方法来解决。位于 Shop.rb

  def id
    _id.to_s
  end

我认为这是因为 MongoDB 默认将 _ids 定义为 BSON 对象,但身份验证工作流正在查找字符串。