Question

Hi Guys I run a sinatra application with mongomapper. I have models called Movie(Document) and Cover(EmbeddedDocument).I embed covers into movies using

@movie.covers << @cover
@movie.save

This works great. when hit @movies.covers I got the array of embedded documents. But I am not able to destroy the embedded document. I tried something like this

@movie.covers.each do |c|
c.destroy
end

NoMethodError: undefined method `destroy' for #<Cover:0xb7b20734>
 from (irb):5
 from /usr/lib/ruby/gems/1.8/gems/mongo_mapper-0.6.8/lib/mongo_mapper/associations/proxy.rb:85:in `call'
 from /usr/lib/ruby/gems/1.8/gems/mongo_mapper-0.6.8/lib/mongo_mapper/associations/proxy.rb:85:in `method_missing'
 from /usr/lib/ruby/gems/1.8/gems/mongo_mapper-0.6.8/lib/mongo_mapper/associations/proxy.rb:85:in `each'
 from /usr/lib/ruby/gems/1.8/gems/mongo_mapper-0.6.8/lib/mongo_mapper/associations/proxy.rb:85:in `send'
 from /usr/lib/ruby/gems/1.8/gems/mongo_mapper-0.6.8/lib/mongo_mapper/associations/proxy.rb:85:in `method_missing'
 from (irb):4
 from :0

Can anyone temme how to destroy it? It would be great if someone enlightens me how to update the embedded document.

Was it helpful?

Solution

Covers are stored as an array within movie object, therefore you can do e.g.:

@movie.covers.clear
@movie.save

or if you want to be selective

@movie.covers.delete_if {|cover| cover.name == "bla"}
@movie.save

OTHER TIPS

This works if your deleting based on an attribute like a name, but if you already know the id and want to delete it, use this trick from p-rob's tubmlr post:

def destroy
@phone_number = @person.phone_numbers.find(params[:id])
@person.phone_numbers.delete_if{|phone_number| phone_number.id == @phone_number.id}
if @person.save
redirect_to @person
  else
    flash[:error] = "dag, yo."
  end
end

I really struggled with this :(

here is a quick and dirty complete gist for deleting an embedded document from an association. Repeated here:

class Period
  include MongoMapper::EmbeddedDocument

  key :text, String

  embedded_in :schedule

  def to_s
    text
  end

end

class Schedule
  include MongoMapper::Document

  key :name, String

  many :periods

  def to_s
    text = "#{name}, periods: " + periods.join(', ')
  end

end

s1 = Schedule.create(:name => "Thursday",
  :periods => [
    Period.new(:text => "Morning"),
    Period.new(:text => "Afternoon"),
    Period.new(:text => "Evening")
  ])
puts s1
#Thursday, periods: Morning, Afternoon, Evening

s1.periods.delete_if{|p| p.text == 'Afternoon'}
s1.save
puts s1
# Thursday, periods: Morning, Evening
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top