需要使用Rails / Mongoid进行MongoDB建模的建议

时间:2014-02-05 01:55:11

标签: ruby-on-rails ruby mongodb mongoid

我正在制作简历模板应用程序。该项目使用Rails 4.0,Devise,MongoDB和bootstrap。

这就是我的模型现在的结构。我正在使用Polymorphic关联,以便在应用程序增长时允许更多灵活性,并且用户可以拥有多个简历。我省略了一些不相关的模型代码和一些较小的模型,如教育,与我的问题无关的技能:

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  has_many :resumes
  has_many :educations, as: :educatable
  has_many :skills, as: :skillable
  has_many :positions, as: :positionable
  has_one  :address, as: :addressable

  field :name,               :type => String
  field :email,              :type => String, :default => ""
  field :encrypted_password, :type => String, :default => ""

  validates_presence_of :name
  validates_uniqueness_of :name, :email

class Resume
  include Mongoid::Document
  include Mongoid::Timestamps

  belongs_to :user
  has_many :educations, as: :educatable
  has_many :skills, as: :skillable
  has_many :positions, as: :positionable
  has_one :address, as: :addressable

  field :objective, :type => String

  validates_presence_of :objective

end

我正在实施以下功能:

  • 身份验证(已完成)
  • 用户可以查看简历(已完成)
  • 用户可以创建简历(进行中)

一位朋友建议MongoDB旨在为每个模型存储创建所需的数据,而不是通过关系访问它。在这种情况下,他建议除了用户模型之外,我应该启用简历模型来存储职位,教育,技能和地址。只使用了RDBMS,我对如何处理“用户可以创建简历”功能感到困惑,我想知道是否有人可以建议我应该如何建模?

以下是我的路线快照:

Tecume::Application.routes.draw do

  devise_for :users, :controllers => { :registrations => "registrations"} 
    resources :users do 
      resources :resumes, only: [:show, :new, :create]
    end

    root 'pages#home'



  get '/ui/:action', controller: 'ui'
end

1 个答案:

答案 0 :(得分:1)

评论太小,所以我会在答案中挥手。

你的朋友在谈论嵌入式文件:

Mongoid对象基本上是一个包含在类中的Hash。当然,ActiveRecord对象几乎是一回事。但是,MongoDB可以很容易地拥有Hash字段和Array字段;如果你在一个类中包装其中一个Hash字段,那么你几乎有一个embeds_one关系;如果你使用Hashes填充一个Array字段并将它们全部包装在类中,那么你几乎就会有embeds_many的关系。

MongoDB没有JOIN,所以如果你需要一次查询两件事,他们要么反规范化并复制数据,要么将一件事嵌入到另一件事物中。例如,如果您想查找惠斯勒人员的所有简历,并且您正在使用has_one,那么您必须找到其城市为惠斯勒的所有地址:

addr_ids = Address.where(:city => 'Whistler').pluck(:id)

然后单独执行查询以查找简历:

Resume.where(:address_id.in => addr_ids)

如果您使用嵌入式文档,那么您只需查看嵌入式文档:

Resume.where('address.city' => 'Whistler')

同样对于急切加载:嵌入式文档作为其父文档的一部分来自数据库,非嵌入式文档需要单独查询。

粗略的经验法则:如果某些事物需要成为一个实体,那么传统的has_manyhas_one关系是有意义的,如果某些东西只存在于其他事物中然后embeds_oneembeds_many才有意义。