gpt4 book ai didi

ruby-on-rails - Rails - 抽象类定义和文件命名的最佳实践

转载 作者:行者123 更新时间:2023-12-03 21:45:37 24 4
gpt4 key购买 nike

我想定义3个类:

  • 一个 MotherClass (抽象,无法推断)
  • 一个 SubClassA (继承自 MotherClass )
  • 一个 SubClassB (继承自 MotherClass )

  • 在 Rails 中声明它的最佳解决方案是什么?

    1. 将所有内容放入 app/models/
  • MotherClass < AR::Base在 app/models/mother_class.rb
  • SubClassA < MotherClass在 app_models/sub_class_a.rb
  • SubClassB < MotherClass在 app/models/sub_class_b.rb

  • 优点:实现起来不是很复杂

    不方便:模型文件夹中的一大堆

    2.为两个子类创建一个模块
  • MotherClass < AR::Base在 app/models/mother_class.rb
  • MotherModule::SubClassA < MotherClass在 app/models/mother_module/sub_class_a.rb
  • MotherModule::SubClassB < MotherClass在 app/models/mother_module/sub_class_b.rb

  • 优点:与方案一相同

    不方便:命名 MotherModuleMotherClass有不同的名字,但它们的意思几乎相同

    3.为3个类创建一个模块
  • MotherModule::Base < AR::Base在 app/models/mother_module/base.rb
  • MotherModule::SubClassA < MotherModule::Base在 app/models/mother_module/sub_class_a.rb
  • MotherModule::SubClassB < MotherModule::Base在 app/models/mother_module/sub_class_b.rb

  • 优点:很干净

    不方便:需要 Base中的一些功能覆盖(例如 table_name)

    所以我的问题是:Rails 的最佳实践是什么?
    - 如何命名我的类(class)?
    - 他们的目录是什么?

    最佳答案

    首先,我想你一定已经意识到 ruby​​ 没有真正的抽象类。但我们可以近似该行为。在这样做的同时,听起来你对我将尝试解决的组织结构有偏好。

    然而,我必须首先说,我很惊讶你从组织的角度如此强烈地解决这个问题。我首先想到的是我是否真的想要实现单表继承,然后让它驱动组织问题。通常这里的答案是单表继承并不是你真正想要的。但是......让我们潜入!

    使用单表继承

    以下是使用单表继承来利用和组织模型的标准方法:

    # app/models/mother_class.rb
    class MotherClass < ActiveRecord::Base
    # An "abstract" method
    def method1
    raise NotImplementedError, "Subclasses must define `method1`."
    end

    def method2
    puts method1 # raises NotImplementedError if `method1` is not redefined by a subclass
    end
    end

    # app/models/sub_class_a.rb
    class SubClassA < MotherClass
    def method1
    # do something
    end
    end

    # app/models/sub_class_b.rb
    class SubClassB < MotherClass
    def method1
    # do something
    end
    end

    鉴于上述情况,我们会在调用 MotherClass.new.method2 时遇到异常。但在调用 SubClassA.new.method2 时不会或 SubClassB.new.method2 .所以我们已经满足了“抽象”的要求。从组织上讲,您称这在模型文件夹中是一团糟……如果您有大量这些子类之类的东西,我可以理解。但是,请记住,即使在单表继承中,父类也是一个模型,并且/应该可以这样使用!所以,也就是说,如果你真的想更好地组织你的模型文件系统,那么你可以自由地这样做。例如,您可以这样做:
  • app/models/<some_organizational_name>/mother_class.rb
  • app/models/<some_organizational_name>/sub_class_a.rb
  • app/models/<some_organizational_name>/sub_class_b.rb

  • 在此,我们保持所有其他内容(即每个模型的代码)相同。我们不会以任何方式对这些模型进行命名空间,我们只是在组织它们。为了完成这项工作,只需帮助 Rails 找到模型,因为我们已经将它们放在模型文件夹的子文件夹中,没有任何其他线索(即没有命名空间)。请引用 this other Stack Overflow post为了这。但是,简而言之,您只需将以下内容添加到您的 config/application.rb 文件中:
    config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**/}')]

    使用 Mixin

    如果您认为单表继承不是您想要的(实际上它们通常不是),那么 mixins 可以为您提供相同的准抽象功能。而且,您可以再次灵活地组织文件。 mixin 的常见组织模式是这样的:
    # app/models/concerns/mother_module.rb
    module MotherModule
    extend ActiveSupport::Concern

    # An "abstract" method
    def method1
    raise NotImplementedError, "Subclasses must define `method1`."
    end

    def method2
    puts method1 # raises NotImplementedError if `method1` is not redefined
    end
    end

    # app/models/sub_class_a.rb
    class SubClassA
    include MotherModule

    def method1
    # do something
    end
    end

    # app/models/sub_class_b.rb
    class SubClassB
    include MotherModule

    def method1
    # do something
    end
    end

    使用这种方法,我们在调用 SubClassA.new.method2 时仍然不会出现异常。或 SubClassB.new.method2因为我们已经在“子类”中覆盖了这些方法。而且由于我们不能真正调用 MotherModule#method1直接它肯定是一个抽象方法。

    在上述组织中,我们收集了 MotherModule进入模型/关注文件夹。这是目前 Rails 中 mixin 的常见位置。你没有提到你正在使用的 Rails 版本,所以如果你还没有 models/concerns文件夹,您将要制作一个,然后从那里制作 rails 自动加载模型。这将再次在 config/application.rb 中使用以下行完成:
    config.autoload_paths += Dir[Rails.root.join('app', 'concerns', '{**/}')]

    在我看来,使用 mixins 方法的组织简单明了 SubclassASubClassB是(显然)模型,因为它们包括 MotherModule担心他们得到 MotherModule 的行为.如果您想将子类模型有组织地分组到一个文件夹中,那么您当然仍然可以这样做。只需使用上面单表继承部分末尾概述的相同方法即可。但我可能会保留 MotherModule仍然位于模型/关注文件夹中。

    关于ruby-on-rails - Rails - 抽象类定义和文件命名的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24402965/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com