Skip to content

Instantly share code, notes, and snippets.

@asavartsov
Created February 17, 2012 16:49
Show Gist options
  • Save asavartsov/1854321 to your computer and use it in GitHub Desktop.
Save asavartsov/1854321 to your computer and use it in GitHub Desktop.
Mongoid 3.0, Paperclip, embedded, accepts_nested_attributes_for and allow_destroy with optional description
-# JS stuff here is quick and dirty. Good programmer will put all link_to_function stuff into helpers
-# like described here (http://railscasts.com/episodes/197-nested-model-form-part-2)
-# or even will do js stuff in some unobtrusive way
= form_for @some_model, :html => {:multipart => true} do |f|
= f.fields_for :photos do |photo|
.photo-field
- if photo.object.new_record?
-# This stuff is for new fields from form builder
= photo.text_field :description
= photo.file_field :file
= link_to_function "Remove", "$(this).parents('.photo-field').remove();"
- else
-# This stuff is for existing photos
= photo.text_field :description
= photo.object.file_file_name
= photo.hidden_field :_destroy, :class => 'destroy'
= link_to_function "Remove", "$(this).parents('.photo-field').hide(); $(this).siblings('.destroy').val('1')"
-# You should generate the Remove link here too, but there is to much creepy inline js here so I omitted it
= link_to_function "Add", "id = new Date().getTime(); $(this).parent().append('<input id=\"some_model_photos_attributes_' + id +'_description\" name=\"some_model[photos_attributes][' + id + '][description]\" type=\"text\"> <input id=\"some_model_photos_attributes_' + id +'_file\" name=\"some_model[photos_attributes][' + id + '][file]\" type=\"file\">');"
gem 'rails', '3.2.1'
gem 'mongoid', :git => 'git://github.com/mongoid/mongoid.git'
gem 'mongoid-paperclip', :require => "mongoid_paperclip"
# if you're using rspec (should be temporary until mongoid-rspec will be updated to mongoid 3.0)
# group :test do
# gem "mongoid-rspec", :git => 'https://github.com/tanordheim/mongoid-rspec.git', :branch => 'mongoid_3_0'
# end
class Photo
include Mongoid::Document
include Mongoid::Paperclip
field :description, :type => String
has_mongoid_attached_file :file
# I use polymorphic relations because I need Photo to be embedded in many models
# It's not required to achieve working Paperclip
embedded_in :paparazzi, :polymorphic => true
attr_accessible :description, :file
# For reasons unknown Paperclip callbacks prevent parent model from destroying when
# they called by Mongoid's cascade_callbacks, so we will delete attachments by self
skip_callback(:destroy, :before, :prepare_for_destroy)
skip_callback(:destroy, :after, :destroy_attached_files)
set_callback(:destroy, :after) do |photo|
photo.file.destroy
end
end
class SomeModel
include Mongoid::Document
# :cascade_callbacks never mentioned in documentation for mongoid-paperclip
# but it's obviously required to get photos working as far as file processing
# done by Paperclip callbacks
embeds_many :photos, :cascade_callbacks => true, :as => :paparazzi
# this kind of reject_if allows user to set empty description, but will filter
# file fields with no file selected
accepts_nested_attributes_for :photos, :allow_destroy => true,
:reject_if => lambda { |photo| photo[:file].blank? if not photo[:_destroy] }
attr_accessible :photos_attributes
end
@mikekolganov
Copy link

Very helpful, thanks a lot!

@TangMonk
Copy link

mongoid 4 not work for _destroy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment