2

我已经spree成功安装了gem。我不需要spree_frontend。这里是Gemfile

gem 'spree_core', '4.2.0.rc2'
gem 'spree_backend', '4.2.0.rc2'
gem 'spree_sample', '4.2.0.rc2'
gem 'spree_cmd', '4.2.0.rc2'
gem 'spree_auth_devise', '~> 4.2'

所以我想扩展我ApplicationController的 from Spree's BaseController。这是代码:

class ApplicationController < Spree::BaseController
  include Spree::Core::ControllerHelpers::Order
end

但我收到以下错误:

uninitialized constant Spree::BaseController (NameError)

如何从已安装的 Spree gem 的控制器中扩展我的控制器?

4

4 回答 4

4

您遇到的问题是Spree::BaseController已经继承自ApplicationController; 见https://github.com/spree/spree/blob/master/core/app/controllers/spree/base_controller.rb。这是为了让您在 Spree 看到之前ApplicationController定义类似和类似的基本功能。current_user

以相反的方式声明它们也会创建循环依赖,结果类加载失败。在不改变 Spree 本身的情况下,唯一的解决办法是做其他事情。

相反,要将您的控制器Spree::BaseController用作超类,首先ApplicationController以更常见的方式定义,例如:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # ...
end

然后发明一个新的抽象控制器,供您自己使用,它继承自 Spree,例如让我们命名它StoreBaseController

# app/controllers/store_base_controller.rb
class StoreBaseController < Spree::BaseController
  include Spree::Core::ControllerHelpers::Order
  # ...
end

现在StoreBaseController可以在ApplicationController定义更具体的控制器时使用它来代替。它之所以有效,是因为它不会在继承树中创建循环,现在看起来像这样:

控制器层次结构

注意:如果您还使用该rails generator命令从模板生成控制器或脚手架,请注意生成器已ApplicationController在模板中进行硬编码,因此您需要在创建后对其进行修改。

于 2021-01-14T23:38:55.980 回答
1

有什么理由需要严格扩展ApplicationController吗?

我建议您使用另一种方法来创建一个新的 Base 控制器类,然后从中继承所有子类并留给ApplicationController基本导轨

app/controller/my_base_controller.rb

class MyBaseController < Spree::BaseController
  def foo
    # ...
  end
end

app/controller/my_resources_controller.rb

class MyResourcesController < MyBaseController
  def bar
    # ...
  end
end
于 2021-01-13T13:18:13.797 回答
0

正如错误所述,Spree::BaseController未在您的应用程序中定义 - 它在spree-coregem 中定义。如果您在本地重新创建基本控制器的文件路径,即app/controllers/spree/,将代码从控制器复制并粘贴到本地base_controller.rb,您可以对其进行编辑并添加自定义功能。

请注意,它仍将继承自ApplicationController,但您可以将任何想要放入的代码ApplicationController放入此处,并让您的类继承自Spree::BaseContoller,效果将是相同的。

于 2021-01-10T18:24:09.550 回答
-1

嗯,我尝试了你想做的,但我成功了(?)

class PagesController < Spree::BaseController
  include Spree::Core::ControllerHelpers::Order
end

在控制台中

2.6.5 :006 > pp PagesController.ancestors
[PagesController,
 Spree::Core::ControllerHelpers::Order,
 #<Module:0x00007fca27610410>,
 Spree::BaseController,
 Spree::Core::ControllerHelpers::CurrencyHelpers,
 Spree::Core::ControllerHelpers::StrongParameters,
...

我在用着

  • 红宝石 2.6.5
  • 导轨 6.0.3.4
  • bundle update在 Gemfile 中添加你的 spree 宝石后运行

所以我认为这是要求或自动加载的问题

  • 你的rails版本是什么?6?spree >= 4.1 应该使用 rails >= 6
  • Spree::BaseController 是否存在于 Rails 控制台中?
  • Bundler.require(*Rails.groups)在吗config/application.rb
  • 宝石是否包含在 Gemfile 的正确组中?例如:狂欢宝石在 :production 组中。
  • 里面有config.load_defaults 6.0config/application.rb
于 2021-01-15T14:46:21.340 回答