Mongoid - array management? insert unique value, delete value if it exists?

I'm trying to make something pretty simple, I believe:

1) insert the value in the array field only if this value is not already specified

2) delete the value if it exists in the array

I just don’t know how to do this ... at the moment I am just inserting my value without checking if it already exists: myArray <<obj.id

Thanks,

Alex

ps: using Rails 3.0.3, mongo 1.1.5 and mongoid 2.0.0.rc5

ps2: this is mongodb syntax to achieve what I want, but I have no idea how to do this in mongoid

{ $addToSet : { field : value } } 

Adds a value to the array only if it is no longer in the array, if the field is an existing array, otherwise it sets the field for the value of the array if the field is absent. If the field is present but not an array, an error condition occurs.

To add a lot of valueest.update

 { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } $pop { $pop : { field : 1 } } 

deletes the last element in the array (added in 1.1)

 { $pop : { field : -1 } } 

removes the first element in an array (ADDED in 1.1) |

+7
source share
4 answers

You want to use the add_to_set method as described here (several): http://mongoid.org/en/mongoid/docs/persistence.html#atomic

Example:

 model = Model.new model.add_to_set(:field, value) model.save 

You can give it a single value or even an array of values. The latter will use the mongo $each qualifier along with $addToSet when adding each element of your array to the field you specify.

+10
source

According to Chris Hawk of the Mongoid googlegroup:

Arrays in Mongolian documents are simple Ruby arrays. See Docs for the Array class: http://www.ruby-doc.org/core/classes/Array.html

So, for insertion you can simply do:

 array << object unless array.include?(object) 

And to delete:

 array.delete(object) 
+8
source

worth mentioning in mongoid starting with 2.0.0pre4. I do not see addToSet support. mongo_mapper (while imo is less supported :() supports this using the push_uniq method.

and in mongoid, if you work directly with the relationship method, you don’t need to do include ?. if you work with the array directly, you do.

Example:

 class Person include Mongoid::Document has_and_belongs_to_many :pets ## or has_many :pets, :stored_as => :array if your not using the latest mongoid end #when using .pets no need to check, mongoid checks for you to ensure you can only add the same pet once. pet = Pet.find("294x29s9a9292") p = Person.find("42192189a92191a") p.pets << pet #when using pet_ids, you do need to check: pet = Pet.find("294x29s9a9292") p = Person.find("42192189a92191a") p.pet_ids << pet.id unless p.pet_ids.include? pet.id 
0
source

You can use the pull operator , which is atomic, to remove a single element. Here's an example where l is a link to a document with an array field:

 l.array = [1, 2, 3] l.save l.pull(array: 1) # atomically removes 1, leaving [2, 3] 

Adding can be done using add_to_set , as mentioned earlier:

 l.array = [2, 3] l.save l.add_to_set(array: 1) # atomically adds 1, resulting in [2, 3, 1] 

Here is a link to the current Mongoid documentation of Atomic operators.

0
source

All Articles