Reputation: 1453
I have a rails app which originally used Paperclip for file uploads, however, as I saw that CarrierWave apparently had a 'persistant upload' type feature over form redisplays, I decided to give that a try.
In my view I have the following:
= f.input :attachment
= f.hidden_field :attachment_cache
Which correctly caches the file if the form fails validation and is redisplayed, however when I correct the validation errors and resubmit, the attachment is not processed.
Started POST "/section/model" for 127.0.0.1 at 2012-03-20 08:51:56 +0000
Processing by Client::WishesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zkdPQBsAnsNzx555rkwZ5+clfnLaXg+NtL+GdFei188=", "model"=>{"title"=>"Sample", "content"=>"Sample content", "contact_name"=>"Mr Sample", "contact_email"=>"sample@example.com", "attachment_cache"=>"20120320-0851-42559-1644/SampleAttachment.pdf"}, "commit"=>"Create Wish"}
Client Load (0.3ms) SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 1 LIMIT 1
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `models` (`attachment`, `client_id`, `contact_email`, `contact_name`, `content`, `created_at`, `status`, `title`, `updated_at`, `upload_content_type`, `upload_file_name`, `upload_file_size`, `upload_updated_at`) VALUES (NULL, 1, 'sample@example.com', 'Mr Sample', 'Sample content', '2012-03-20 08:51:56', 'Unresolved', 'Sample', '2012-03-20 08:51:56', NULL, NULL, NULL, NULL)
It appears to be correctly passing the attachment via the attachment_cache in the params, but it isn't then saving the attachment as it doesn't have a params[:model][:attachment] field.
It doesn't say any further steps on the carrierwave section for making uploads work across form redisplays on the CarrierWave GitHub.
Upvotes: 7
Views: 3298
Reputation: 415
To add on to @marko's answer:
If you are using Active Admin, you'll need to add the cached file to the permit_params line.
permit_params: :title, :file, :file_cache
Upvotes: 0
Reputation: 21
This will solve your issue 100%
Please have a look at
accepts_nested_attributes_for :avatars, allow_destroy: true,
reject_if: lambda { |avatar| avatar[:avatar].blank? and avatar[:avatar_cache].blank?}
Here we will reject avatar when both avatar[:avatar]
and avatar[:avatar_cache]
are blank
Upvotes: 2
Reputation: 763
It's a bit of an old question, but it worked for me after I added the strong parameter to the controller, like this:
#controller
def object_params
params.require(:object).permit(:attachment, :attachment_cache)
end
#view
<%= f.file_field :attachment %>
<%= f.hidden_field :attachment_cache %>
Upvotes: 3
Reputation: 5999
For me, the issue was that I had
accepts_nested_attributes_for :avatars, allow_destroy: true, reject_if: lambda { |avatar| avatar[:file].blank? }
So I was rejecting the file because the file wasn't there
It is important to note that the file itself does not persist, but just the file cache. That is why the carrierwave docs suggest:
It might be a good idea to show the user that a file has been uploaded, in the case of images, a small thumbnail would be a good indicator:
Upvotes: 0
Reputation: 1
The cause is the 'changed?' check, when validation error, we pass the cached file in #{model}_cache field which is not a database table column, so it doesn't save the object because nothing is changed in the AR's point of view.
I did a hack to make this work by creating a method in the model that containing the file: "data" is the the column name
def data_cache=(text)
@changed_attributes.merge!("data" => nil)
super
end
Hope this helps.
Upvotes: 0
Reputation: 1151
Try populating the value of avatar_cache so that when validation fails, it will be pre-populated in the form:
= f.hidden_field :attachment_cache, :value => @model.attachment_cache
Where @model
is the name of your model
This seems to work for me when the same form is reloaded multiple times (i.e. when validation fails multiple times). I think they left this out of the documentation.
Upvotes: 2