Starting a new Rails 4 : VI. Attachments with Carrierwave and Jasny rails 4, carrierwave, minimagick, bootstrap 3, fileupload
- Roadmap
- Carrierwave start with avatar for user
- ActiveRecord integration
- Validations on the model
- User Views
- Bootstrap 3 and Jasny FileUpload
Roadmap
I want to manage attachments : for starting, some avatar for users, and some files linked to projects in future.
First install ImageMagick : it need for all the mini magick stuff (as usual, in /c/dev for me).
Carrierwave start with avatar for user
After installed carrierwave in gemfile (with mini_magick gem too for image processing), starting with :
rails g uploader avatar
witch create app/uploaders/avatar.rb with some change :
include CarrierWave::MiniMagick
def default_url
asset_path [version_name, "default_user_avatar_huge.png"].compact.join('_'))
end
version :small do
process :resize_to_fill => [32, 32]
end
def extension_white_list
%w(jpg jpeg gif png)
end
Where default_user_avatar_huge.png is a fallback avatar image in assets/images. (with a small version 32x32 named small_default_user_avatar_huge.png)
ActiveRecord integration
First add an avatar
string column to the user model, and migrate.
rake g migration AddAvatarToUsers avatar:string
And ajust the models/user.rb :
mount_uploader :avatar, AvatarUploader
Validations on the model
For the file size, check out the solution https://github.com/jnicklas/carrierwave/wiki/How-to%3A-Validate-attachment-file-size and apply it in our model user :
require 'file_size_validator'
class User < ActiveRecord::Base
authenticates_with_sorcery!
...
validates :avatar,
:file_size => { :maximum => 5.megabytes.to_i}
end
Also we validate the processing and the file type (see https://github.com/jnicklas/carrierwave/wiki/How-to%3A-Validate-uploads-with-Active-Record) in models/user.rb :
validates_integrity_of :avatar
validates_processing_of :avatar
And this is the full config/locales/en.yml :
en:
errors:
messages:
wrong_size: "is the wrong size (should be %{file_size})"
size_too_small: "is too small (should be at least %{file_size})"
size_too_big: "is too big (should be at most %{file_size})"
carrierwave_processing_error: "failed to be processed"
carrierwave_integrity_error: "is not an allowed file type"
carrierwave_download_error: "Couldn't download image."
and the models/user.rb :
class User < ActiveRecord::Base
...
mont_uploader :avatar, AvatarUploader
validates :avatar,
:presence => true ,
:file_size => { :maximum => 5.megabytes.to_i}
validates_integrity_of :avatar
validates_processing_of :avatar
end
User Views
In the index view :
%td= image_tag user.avatar.small.url
In the form view : (the remove_avatar
and avatar_cache
are specials fields build by carrierwave for removing the avatar and keep a cache of uploaded image when the form is reloaded if some validation has failed).
= f.input :avatar, :as => :file
= f.input :remove_avatar, :as => :boolean
= f.input :avatar_cache, :as => :hidden
Add also those fields to the method user_params
in the controllers/users_controller.rb
In the show view :
= link_to image_tag(@user.avatar.small.url), '#modal_avatar', :role => 'button', 'data-toggle'=>'modal'
...
#modal_avatar.modal.fade
.modal-dialog
.modal-content
.modal-header
= button_close_modal
%h4 Image
.modal-body
= image_tag @user.avatar.url, :style => 'max-height: 400px;max-width: 400px;margin: 0 auto;display:block;', :class => 'img-thumbnail'
.modal-footer
The modal dialog show the image in full size (CSS have to move…).
Bootstrap 3 and Jasny FileUpload
I use a part of Jasny Bootstrap enhancement : go to http://jasny.github.io/bootstrap/javascript.html#fileupload, click on the button ‘download’ and copy the .css and the .js files you just just get in the correspondent /assets/ folder.
Now in the \form.html.haml replace the
= f.input :avatar, :as => :file
with
= render partial: 'file_upload', :locals => {f: f}
and create the partial app/views/users/_file_upload.html.haml :
.control-group.file.optional.user_avatar
%label.file.optional.control-label{for: "user_avatar"} Avatar
.controls
.fileupload.fileupload-new{"data-provides" => "fileupload"}
.fileupload-new.thumbnail{style: "width: 50px; height: 50px;"}= image_tag @user.avatar.small.url
.fileupload-preview.fileupload-exists.thumbnail{style: "width: 50px; height: 50px;"}
%span.btn.btn-file.btn-primary
%span.fileupload-new Select image
%span.fileupload-exists Change
= f.input_field :avatar, :as => :file
= link_to "Remove", "#", class: "btn fileupload-exists", "data-dismiss" => "fileupload"
comments powered by Disqus