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
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
class List
include Mongoid::Document
has_and_belongs_to_many :foods
embedded_in :user
belongs_to: popular_list
end
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.