0

I have three documents.

User
List
Food

A list can have many foods and is embedded inside the user document. I have an action in my controller that when an user is done with a food item, loops through the user's list and removes any association between a list and the particular food the user is completed with.

@user.lists.to_a.each do |list|

  list.food_ids.to_a.map do |food_id|
    if food_id.eql? params[:food_id]

      food = Food.find(params[:food_id])

      # Pull food from list
      list.pull(:foods, food)

    end
  end
end

@user.save

My models

User

class User

  # INCLUDES
  # ========
  include Mongoid::Document

  include Mongoid::Paperclip

  include Mongoid::MultiParameterAttributes

  include Mongoid::Spacial::Document

  # EMBEDDING
  # =========
  embeds_many :lists

  # NESTED ATTRIBUTES
  # =================
  accepts_nested_attributes_for :lists
end

List

class List
  include Mongoid::Document

  has_and_belongs_to_many :foods

  embedded_in :user

  belongs_to: popular_list  
end

Food

class Food

  # INCLUDES
  # ========
  include Mongoid::Document

  include Mongoid::Timestamps

  include Mongoid::Paperclip

  include Mongoid::Spacial::Document

  # ASSOCIATIONS
  # ============
  belongs_to :user

  has_and_belongs_to_many :popular_lists

end

The problem is, my code does not remove the food item from the list. My question is how can I loop through an array, pull an item from that array, and expect the new array to be saved?

1
  • Could you post your List and Food definitions? Mongoid does not allow references to embedded models and will raise an exception if I try to reproduce this. Commented Mar 29, 2013 at 21:23

1 Answer 1

1

It's not working because of two problems: First, you cannot embed List, because you have references (relations) from/to it. Make it an own collection with a normal belongs_to :user.

You cannot have relations to embedded models, because the other side will only store the id. If you use that relation, Mongoid will call MyEmbeddedModel.find(related_id) which cannot find the embedded model, because it's inside another document and not an own collection.

Second, your code is missing the counterparts for belongs_to :user and has_and_belongs_to_many :foods. The documentation states: Definitions are required on both sides to the relation in order for it to work properly. If you add these (see my gist), Mongoid will raise an error that also suggests not to embed List:

(Mongoid::Errors::MixedRelations)

Problem: Referencing a(n) List document from the Food document via a relational association is not allowed since the List is embedded.

Summary: In order to properly access a(n) List from Food the reference would need to go through the root document of List. In a simple case this would require Mongoid to store an extra foreign key for the root, in more complex cases where List is multiple levels deep a key would need to be stored for each parent up the hierarchy. Resolution: Consider not embedding List, or do the key storage and access in a custom manner in the application code.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Pascal. Your answer helped me understand the association issues I have and will help me fix my problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.