Reputation: 1267
I have mongodb document like this and want to remove one element form unpublished array which is in resource_well
{
"_id": ObjectId("4fa77c808d0a6c287d00000a"),
"production_status": "Unscheduled",
"projected_air_date": null,
"published": false,
"resource_well": {
"published": [
],
"unpublished": {
"0": ObjectId("4fa795038d0a6c327e00000e"),
"1": ObjectId("4fa795318d0a6c327e00000f"),
"2": ObjectId("4fa795508d0a6c327e000011"),
"3": ObjectId("4fa796f48d0a6c327e000013")
}
},
"segment_status": "Draft",
}
Code in controller
segment = Segment.find(params[:segment_id])
# segment.resource_well[params['resource_well_type']].class => Array
# segment.resource_well[params['resource_well_type']].inspect => [BSON::ObjectId('4fa795038d0a6c327e00000e'), BSON::ObjectId('4fa795318d0a6c327e00000f'), BSON::ObjectId('4fa795508d0a6c327e000011'), BSON::ObjectId('4fa796f48d0a6c327e000013')]
segment.resource_well[params['resource_well_type']].delete(params[:asset_ids])
segment.save
Not able remove an element form array
Upvotes: 0
Views: 3033
Reputation: 3402
Your ODM (or ORM) provides associations for you so that you can take advantage of having the ODM manage the links for you. So you should use the associations, otherwise you risk hanging yourself. Just make sure to specify the relationship correctly, and use the generated method named by the association and its methods, e.g. resource_well.unpublished <<, resource_well.unpublished.delete. The following models and tests work for me. The inconvenience is that the delete method on the association takes an object, e.g., other.delete(object) and not a string or conditions, so if you start with a string, you have to supply an object in order to delete it. Note that other.delete_all(conditions) or other.where(conditions).delete_all remove both actual documents as well as the association, which is not what you were looking for. Anyway, hope that this helps.
Models
class Segment
include Mongoid::Document
field :production_status, type: String
field :projected_air_date, type: Date
field :published, type: Boolean
field :segment_status, type: String
embeds_one :resource_well
end
class ResourceWell
include Mongoid::Document
embedded_in :segment
has_and_belongs_to_many :published, :class_name => 'Resource'
has_and_belongs_to_many :unpublished, :class_name => 'Resource'
end
class Resource
include Mongoid::Document
field :name, type: String
end
Test
require 'test_helper'
class Object
def to_pretty_json
JSON.pretty_generate(JSON.parse(self.to_json))
end
end
class SegmentTest < ActiveSupport::TestCase
def setup
Segment.delete_all
end
test 'resource_well unpublished delete' do
res = (0..3).collect{|i| Resource.create(name: "resource #{i}")}
seg = Segment.create(
production_status: 'Unscheduled',
projected_air_date: nil,
published: false,
resource_well: ResourceWell.new(unpublished: res[0..2]),
segment_status: 'Draft')
seg.resource_well.unpublished << res[3] #just an append example
puts seg.to_pretty_json
id = res[0]['_id'].to_s
puts "id: #{id}"
resource_obj = Resource.find(id)
puts "resource: #{resource_obj.inspect}"
Rails.logger.debug("delete: #{resource_obj.inspect}")
seg.resource_well.unpublished.delete(resource_obj)
puts Segment.find(:all).to_pretty_json
end
end
Result
# Running tests:
{
"_id": "4fa839197f11ba80a9000006",
"production_status": "Unscheduled",
"projected_air_date": null,
"published": false,
"resource_well": {
"_id": "4fa839197f11ba80a9000005",
"published_ids": [
],
"unpublished_ids": [
"4fa839197f11ba80a9000001",
"4fa839197f11ba80a9000002",
"4fa839197f11ba80a9000003",
"4fa839197f11ba80a9000004"
]
},
"segment_status": "Draft"
}
id: 4fa839197f11ba80a9000001
resource: #<Resource _id: 4fa839197f11ba80a9000001, _type: nil, name: "resource 0">
[
{
"_id": "4fa839197f11ba80a9000006",
"production_status": "Unscheduled",
"projected_air_date": null,
"published": false,
"resource_well": {
"_id": "4fa839197f11ba80a9000005",
"published_ids": [
],
"unpublished_ids": [
"4fa839197f11ba80a9000002",
"4fa839197f11ba80a9000003",
"4fa839197f11ba80a9000004"
]
},
"segment_status": "Draft"
}
]
.
Finished tests in 0.016026s, 62.3986 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Upvotes: 4
Reputation: 2946
db.collection.update(
{_id : ObjectId("4fa77c808d0a6c287d00000a")},
{ $unset : { "resource_well.unpublished.1" : 1 }}
);
This will remove element [1] of the array.
Also you can read how to implement it using mongoid: http://mongoid.org/docs/upgrading.html
Upvotes: 2