Stage
Image a gallery application.
I have two models Handcraft
and Photos
.
One handcraft may have many photos, suppose I have models like this:
Handcraft(name:string)
Photo(filename:string, description:string, ...)
In _form.html.erb
of handcrafts, there is:
<%= form_for @handcraft, html: {multipart: true} do |f| %>
# ... other model fields
<div class="field">
<%= f.label :photo %><br />
<%= f.file_field :photo %>
</div>
# ... submit button
<% end %>
handcraft.rb
looks like this:
class Handcraft < ActiveRecord::Base
attr_accessible :photo
has_many :photos
mount_uploader :photo, PhotoUploader
# ...
end
photo_uploader.rb
:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_limit => [100, 100]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
Problem
When I submit form, it throws this error:
NoMethodError (undefined method `photo_will_change!' for #<Handcraft:0xb66de424>):
Question
How should I use/configure Carrierwave in this case?
You need to mount the uploader on the field that will store the filename, so your models should look like
class Handcraft < ActiveRecord::Base
attr_accessible :name
has_many :photos
# ...
end
class Photo < ActiveRecord::Base
attr_accessible :filename, :description
mount_uploader :filename, PhotoUploader
# ...
end
and then as it seems you'll be creating the photos through the handcraft form, you should add
accepts_nested_attributes_for :photos
in your Handcraft
class
Then your form will look something like
<%= form_for @handcraft, html: {multipart: true} do |f| %>
# ... other model fields
<%= f.fields_for :photos do |photo| %>
<%= photo.label :photo %><br />
<%= photo.file_field :photo %>
<% end %>
# ... submit button
<% end %>
For the form to display fields for photo, you'll need your Handcraft
instance to have photos
created, this can be done in your new
method in the HandcraftsController
like that:
def new
@handcraft = Handcraft.new
4.times { @handcraft.photos.build }
end
This will make 4 (arbitrary number) fields availables in your form, if somehow you want the user to dynamically add new photos in your form, have a look at nested_form
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With