2011-08-26 74 views
1

这个问题涉及到使用Ruby on Rails 3与MongoMapper和EmbeddedDocument。此外,ManyAssociation。在设计MongoMapper模型时有没有嵌入类的(代码设计)原因?

http://mongomapper.com/documentation/embedded-document.html

的MongoMapper的例子(在上面的链接)显示出两个独立的类:

class Order 
    include MongoMapper::Document 

    many :line_items 
    timestamps! 
end 

class LineItem 
    include MongoMapper::EmbeddedDocument 

    key :name, String 
    key :quantity, Integer 
end 

但这种污染与LineItem全局命名空间。出于上下文的考虑,LineItem是什么?如果我想要另一个模型,比如WishList,还有一个LineItem集合?

因此,有可能嵌入LineItem类的秩序,就像这样:

class Order 
    include MongoMapper::Document 

    many :line_items, :class_name => "Order::LineItem" 
    timestamps! 

    class LineItem 
    include MongoMapper::EmbeddedDocument 

    key :name, String 
    key :quantity, Integer 
    end 
end 

虽然这可能是技术上的罚款(是吗?),稍后我会遇到设计问题?它是否使代码太丑陋?太复杂了?

大概,这种Ruby语言的存在意味着有人认为这是一个好主意?

我一直很喜欢Django的一件事是它如何使用“应用程序”来分组相关模型类(并分隔名称空间)。所以我上面的代码也在Rails中实现。

回答

3

我没有看到任何方法的技术问题。我碰到的问题是,当一个类嵌入到它的父代中,并且也在同一个文件中时,我会忘记它在那里。所以如果你的命名空间为Order::LineItem,你可以在你的“models”文件夹中创建一个“订单”文件夹,并在其中放入“line_item.rb”。

另一个问题是,如果你想有一个控制器Order::LineItem,你还必须命名空间,并把它的文件夹中,并在路由器它看起来就像:

resource :orders do 
    resources :line_items,   :controller => "order/line_items" 
end 

除非你知道你的应用将有多种类型的line_items,我建议不要命名空间 - 如果你做了,你可能会过度编码。例如,如果您稍后需要两种类型的line_items,您甚至可能会发现某些代码可能会在模型之间重复使用 - 如果命名空间为第一个line_item,则可能会发现您将其命名为空间。

在Python中,命名空间被认为是一件好事,应该有更多的命名空间。但是当您考虑Rails应用程序的全局命名空间时,它并不是那么混乱。 Gem作者非常擅长将他们的所有类命名空间保留在他们的一个gem模块中,因此在Rails应用中,您将为每个您使用的gem拥有一个命名空间(Rails本身是5个gem,不知道有多少个全局常量),加上一些Rails包含的文件(例如SecureRandom)。事实证明,将这些文件“恰到好处”真的很好,而且我在实践中发现命名空间冲突很少,您可以轻松解决它们。我只碰到过一次命名空间问题,但有几次我偶然在模型上定义了一个“发送”方法,这是一个更常见的类似影响的问题。