代码之家  ›  专栏  ›  技术社区  ›  Chowlett

Rails:单表继承和模型子目录

  •  3
  • Chowlett  · 技术社区  · 16 年前

    我有一个利用单表继承的纸牌游戏应用程序。我有一个 class Card cards 带列 type ,以及 Card class Foo < Card class Bar < Card ,为了论证)。

    碰巧的是, Foo 是一款由原版卡片印刷而成的游戏 Bar 是一张扩充卡。为了使我的模型合理化,我创建了如下目录结构:

    app/
    + models/
      + card.rb
      + base_game/
        + foo.rb
      + expansion/
        + bar.rb
    

    Rails::Initializer.run do |config|
      config.load_paths += Dir["#{RAILS_ROOT}/app/models/**"]
    end
    

    但是,当我的应用程序从数据库读取卡片时,Rails会抛出以下异常:

    ActiveRecord::SubclassNotFound (The single-table inheritance mechanism failed to locate the subclass: 'Foo'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite Card.inheritance_column to use another column for that information.)

    有没有可能使这项工作,或我注定要一个平面目录结构?

    1 回复  |  直到 16 年前
        1
  •  2
  •   Ceilingfish    16 年前

    也许最好的办法就是把 Foo a类内部 BaseGame 模块。

    ruby模块大致类似于其他语言中的包结构,它是一种将相关代码位划分为逻辑组的机制。它还有其他功能,如mixins(您可以在这里找到解释: http://www.rubyfleebie.com/an-introduction-to-modules-part-1/ )但在这种情况下,它们并不相关。

    您需要稍微不同地引用和实例化类。例如,您可以这样查询:

    BaseGame::Foo.find(:all,:conditons => :here)
    

    或者像这样创建一个实例:

    BaseGame::Foo.new(:height => 1)
    

    Rails支持活动记录模型的模块化代码。您只需要对类的存储位置做一些更改。例如,假设您将类Foo移动到一个模块BaseGame中(如您的示例所示),您需要移动 apps/models/foo.rb apps/models/base_game/foo.rb 。因此,文件树将如下所示:

    app/
     + models/
      + card.rb #The superclass
       + base_game/
          + foo.rb
    

    在类上声明如下:

    module BaseGame
      class Foo < Card
      end
    end
    
    推荐文章