HelloWorld
HelloWorld

Reputation: 4349

How to save embedded classes in mongoid?

I am using Rails 3 with mongoid 2. I have a mongoid class forum, which embeds_many topics. Topics embeds_many forumposts

When I try to save a forumpost doing the following in my controller...

@forum = Forum.find(params[:forum_id])
@forum.topics.find(params[:topic_id]).forumposts.build(:topic_id => params[:forumpost][:topic_id], :content => params[:forumpost][:content], :user_id => current_user.id,:posted_at => Time.now, :created_at => Time.now, :updated_at => Time.now)
if @forum.save

On save I get...

undefined method `each' for 2012-11-14 23:15:39 UTC:Time

Why am I getting that error?

My forumpost class is as follows...

class Forumpost
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  field :content, type: String
  field :topic_id, type: String
  field :user_id, type: String
  field :posted_at, type: DateTime

    attr_accessible :content, :topic_id, :user_id, :posted_at, :created_at, :updated_at

  validates :content, presence: true
  validates :topic_id, presence: true
  validates :user_id, presence: true

    belongs_to :topic
    belongs_to :user

end

Upvotes: 1

Views: 2737

Answers (1)

SporkInventor
SporkInventor

Reputation: 3120

There is alot wrong/wierd with your example code, so lets see if we can start at the start:

You say forum embeds many topics, which embeds many posts. But your model is using a belongs_to association. Belongs_to is used for references which are different than embedded documents. If your Topic model has this:

class Topic
  ...
  embeds_many :forumposts
  ...
end

Then your Forumpost model should have this:

class Forumpost
  ...
  embedded_in :topic
  ...
end

Read up on references vs embedded documents here: http://mongoid.org/en/mongoid/docs/relations.html

Next point, You don't need to put :topic_id into the forumpost since you are building it off the topic.

Next point, don't save the forum, save the forumpost. And instead of doing a build followed by a save, try just doing it as a create in one go.

Next point, instead of setting user_id => current_user.id, try setting user => current_user. This is the magic that the belongs_to association provides... its cleaner and avoids messing around with IDs.

Next point, why do you need both created_at (supplied by Mongoid::Timestamps) and posted_at ?

Last point, you shouldn't need to set the timestamps, they should be set automatically when created/updated (unless for some reason you actually need posted_at).

Try something more like this:

@forum = Forum.find(params[:forum_id])
@topic = @forum.topics.find(params[:topic_id])
if @topic.forumposts.create(:content => params[:forumpost][:content], :user => current_user)
  #handle the success case
else
  #handle the error case
end   

Upvotes: 7

Related Questions