【问题标题】:Most proper way to use inherited classes with shared relations?使用具有共享关系的继承类的最正确方法?
【发布时间】:2012-06-30 21:12:39
【问题描述】:

我有由Game 类继承的TestVisual 类:

class TestVisual < Game
  include MongoMapper::Document  
end

class Game
  include MongoMapper::Document         

  belongs_to :maestra  

  key :incorrect,         Integer
  key :correct,           Integer
  key :time_to_complete,  Integer

  key :maestra_id, ObjectId

  timestamps!

end

如您所见,它属于 Maestra。

所以我可以做Maestra.first.games,它返回[]

但我不能Maestra.first.test_visuals,因为它返回undefined method test_visuals

由于我专门与 TestVisuals 合作,因此我希望实现理想的效果,但仍然让它共享其父 Game 类的属性。

这在 Mongo 中是否可行。如果不是或者没有必要,有没有其他更好的方法可以从 Maestra 到达 TestVisual 对象并仍然让它继承 Game ?

【问题讨论】:

    标签: ruby-on-rails mongodb nosql


    【解决方案1】:

    MongoMapper 中的单集合继承 (SCI) 自动生成选择, 例如,以下产生相同的结果。

    p Game.where(_type: 'TestVisual').all
    p TestVisual.all
    

    另见 mongomapper/lib/mongo_mapper/plugins/sci.rb - MongoMapper::Plugins::Sci::ClassMethods#query

    但是,MongoMapper 不会根据基类的关联自动生成子类的关联, 而且我认为这不应该是意料之中的。

    请注意,SCI 将子类和基类放在同一个 MongoDB 集合中。 如果这不是您想要的,您应该考虑其他模块化机制。

    您可以自己为关联访问器方法定义以下方法,也许这足以满足您的目的? 对于附加或推送等其他关联方法,父方法可能是可行的。

    class Maestra
      include MongoMapper::Document
      key :name, String
      many :games
    
      def test_visuals
        games.where(_type: 'TestVisual')
      end
    end
    

    test/unit/test_visual_test.rb

    require 'test_helper'
    
    def ppp(obj)
      puts obj.inspect.gsub(/, ([^#])/, ",\n\t\\1").gsub(/, #/, ",\n #")
    end
    class TestVisualTest < ActiveSupport::TestCase
      def setup
        Maestra.delete_all
        Game.delete_all
      end
    
      test "inheritance" do
        maestra = Maestra.create(name: 'Fiona')
        maestra.games << Game.create(incorrect: 1, correct: 9, time_to_complete: 60)
        maestra.games << TestVisual.create(incorrect: 2, correct: 8, time_to_complete: 61)
        ppp maestra.games.to_a
        ppp maestra.test_visuals.to_a
      end
    end
    

    输出

    Run options: --name=test_inheritance
    
    # Running tests:
    
    [#<Game _id: BSON::ObjectId('4ff7029a7f11ba6e43000002'),
        _type: "Game",
        correct: 9,
        created_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00,
        incorrect: 1,
        maestra_id: BSON::ObjectId('4ff7029a7f11ba6e43000001'),
        time_to_complete: 60,
        updated_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00>,
     #<TestVisual _id: BSON::ObjectId('4ff7029a7f11ba6e43000003'),
        _type: "TestVisual",
        correct: 8,
        created_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00,
        incorrect: 2,
        maestra_id: BSON::ObjectId('4ff7029a7f11ba6e43000001'),
        time_to_complete: 61,
        updated_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00>]
    [#<TestVisual _id: BSON::ObjectId('4ff7029a7f11ba6e43000003'),
        _type: "TestVisual",
        correct: 8,
        created_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00,
        incorrect: 2,
        maestra_id: BSON::ObjectId('4ff7029a7f11ba6e43000001'),
        time_to_complete: 61,
        updated_at: Fri,
        06 Jul 2012 15:22:02 UTC +00:00>]
    .
    
    Finished tests in 0.026661s, 37.5080 tests/s, 0.0000 assertions/s.
    
    1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
    

    【讨论】:

    • 哇太棒了!非常感谢加里·村上隆。超神!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2011-01-01
    • 2020-11-13
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多