简体   繁体   中英

Pulling from Array in Embedded Document

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM