在设计MongoMapper模型时是否有(代码设计)理由不嵌入类?

时间:2011-08-26 08:32:28

标签: ruby-on-rails mongomapper

这个问题与使用Ruby on Rails 3和MongoMapper以及EmbeddedDocument有关。还有,ManyAssociation。

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设置怎么办?

因此可以在Line中嵌入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的一件事是它如何使用“apps”来分组相关的模型类(并分离命名空间)。所以我上面的代码也在Rails中实现了。

1 个答案:

答案 0 :(得分:3)

我认为这两种方法都没有任何技术问题。我遇到的问题是当一个类嵌入它的父级并且也在同一个文件中时,我会忘记它就在那里。因此,如果您的命名空间为Order::LineItem,则可以在“models”文件夹中创建“order”文件夹,并在其中添加“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个宝石,不知道有多少全局虽然常量),加上Rails包含的一堆文件(例如SecureRandom)。事实证明,将这些文件“放在那里”真的很棒,而且我在实践中发现命名空间冲突很少见,你可以轻松解决它们。我可能只遇到过一次名称空间问题,但有几次我不小心在模型上定义了一个“发送”方法 - 这是一个更常见的问题,具有类似的影响。