Micah Alcorn
Micah Alcorn

Reputation: 2383

Embedded mongoid referencing

My User model has_and_belongs_to_many :conversations.

The Conversation model embeds_many :messages.

The Message model needs to have a sender and a recipient.

I was not able to find referenced_in at the Mongoid documentation.

How do I assign the users in the message? I tried to follow something similar to this implementation, but kept getting BSON::InvalidDocument: Cannot serialize an object of class Mongoid::Relations::Referenced::In into BSON.

November 2013 Update: reference_in no longer works with Mongoid 3.0? Changed to belongs_to and it seems to work the same.

Upvotes: 0

Views: 954

Answers (1)

Micah Alcorn
Micah Alcorn

Reputation: 2383

As it turns out, my structure of the Message referencing the User was appropriate, and the serialization error was related to associating the Users with the Conversation. Here is my structure and the creation steps. I appreciate any feedback on better practices, thanks.

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  has_and_belongs_to_many :conversations
end
class Conversation
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  has_and_belongs_to_many :users
  embeds_many :messages
end
class Message
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  embedded_in :conversation
  embeds_one :sender, class_name: 'User'
  embeds_one :recipient, class_name: 'User'

  field :content
  field :read_at, type: DateTime
  field :sender_deleted, type: Boolean, default: false
  field :recipient_deleted, type: Boolean, default: false

  belongs_to :sender, class_name: "User", inverse_of: :sender, foreign_key: 'sender_id'
  belongs_to :recipient, class_name: "User", inverse_of: :recipient, foreign_key: 'recipient_id'
end

Where before I was trying to @conversation.build(user_ids: [@user_one,@user_two]), the appropriate way is to @conversation.users.concat([@user_one,@user_two]). Then you can simply @conversation.messages.build(sender: @user_one, recipient: @user_two).

Upvotes: 3

Related Questions