Mongoid - how to model data if I want a copy of another model

196 views
Skip to first unread message

Larry

unread,
Mar 19, 2012, 5:00:17 AM3/19/12
to Mongoid
I have the following model:

class User
include Mongoid::Document
store_in :users

field :full_name, :type => String
end

class Message
include Mongoid::Document

embeds_one :sender, :class_name => "User"

field :text, :type => String
end

I would like to store User and Message in separated standalone
collections so that they could be queried directly, and I would like
to have one copy of user for sender in each Message entry. Is my model
correct for this kind of request?

I feel that embeds_one :sender, :class_name => "User" is not the
correct the way to do this. Does it mean what I should do is simply:
field :sender, :type => User ?

Durran Jordan

unread,
Mar 19, 2012, 5:23:51 AM3/19/12
to mon...@googlegroups.com
You're going to need a separate model if you want to embed the user data inside the message. When denormalizing like this I generally namespace one of them, and create a module with the common fields to include in both - maybe in your case you can call it Sender?

class Sender
  include Mongoid::Document
  include UserProperties

  class << self
    def from_user(user)
      Sender.new(user.attributes)
    end
  end
end


class User
  include Mongoid::Document
  include UserProperties
end

module UserProperties
  extend ActiveSupport::Concern
  included do
    field :full_name, type: String
  end

end

class Message
  include Mongoid::Document
  embeds_one :sender
end

You also don't need the :store_in macro on User - by default it's name would be "users".

2012/3/19 Larry <thehidd...@gmail.com>

Larry

unread,
Mar 20, 2012, 5:58:50 AM3/20/12
to Mongoid
Thanks a lot. That's very helpful.
> 2012/3/19 Larry <thehiddende...@gmail.com>

Larry

unread,
Mar 20, 2012, 8:09:08 AM3/20/12
to Mongoid
Do I have to address an embedded_in :Message in the Sender model?

If I want to embed sender into more than one model, is it possible?

On Mar 19, 5:23 pm, Durran Jordan <dur...@gmail.com> wrote:
> 2012/3/19 Larry <thehiddende...@gmail.com>

Durran Jordan

unread,
Mar 20, 2012, 9:43:17 AM3/20/12
to mon...@googlegroups.com
You can embed it in as many models as you like - I tend to go the polymorphic route in this case:


class Sender
  include Mongoid::Document
  embedded_in :sendable, polymorphic: true

end

class Message
  include Mongoid::Document
  embeds_one :sender, as: :sendable
end

class SomeOtherSendable
  include Mongoid::Document
  embeds_one :sender, as: :sendable
end

etc...

2012/3/20 Larry <thehidd...@gmail.com>

Larry

unread,
Mar 20, 2012, 11:11:54 AM3/20/12
to Mongoid
Really nice, thanks a lot.

On Mar 20, 9:43 pm, Durran Jordan <dur...@gmail.com> wrote:
> You can embed it in as many models as you like - I tend to go the
> polymorphic route in this case:
>
> class Sender
>   include Mongoid::Document
>   embedded_in :sendable, polymorphic: true
> end
>
> class Message
>   include Mongoid::Document
>   embeds_one :sender, as: :sendable
> end
>
> class SomeOtherSendable
>   include Mongoid::Document
>   embeds_one :sender, as: :sendable
> end
>
> etc...
>
> 2012/3/20 Larry <thehiddende...@gmail.com>
Reply all
Reply to author
Forward
0 new messages