How to: use carrierwave with devise

ZhaoZijie edited this page Oct 10, 2014 · 7 revisions
Clone this wiki locally

These instructions assume:

  • you've followed the instructions on CarrierWave installation, and generating an AvatarUploader class
  • already have a Devise model named User
  • you wish to add an avatar to that model using CarrierWave, mounted on a column named avatar

1) Migrate to add the new avatar column to the User model

class AddUserAvatar < ActiveRecord::Migration
  def change
    add_column :users, :avatar, :string
  end
end

2) Add the CarrierWave avatar to your User model

  • Add a mount_uploader line at the top of the User class
  • Add :avatar, :avatar_cache, and :remove_avatar to the list of accessible attributes you already have generated by Devise.
  • Optional: Add avatar validations

This looks something like:

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :remember_me, :avatar, :avatar_cache, :remove_avatar

  validates_presence_of   :avatar
  validates_integrity_of  :avatar
  validates_processing_of :avatar
end

For Rails 4 with strong parameters:

Instead of using an attr_accessible, include the attributes in the devise parameter sanitizer in the ApplicationController:

class ApplicationController < ActionController::Base
  before_filter :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password,
      :password_confirmation, :remember_me, :avatar, :avatar_cache) }
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password,
      :password_confirmation, :current_password, :avatar, :avatar_cache) }
  end
end

3) Add avatar upload to the sign up form (optional)

Assuming you have generated custom Devise views in the standard location, and that you are using Haml, this file is something like app/views/devise/registrations/new.html.haml. You need to:

  • Add :multipart => true to the :html hash passed to form_for.
  • Add a file_field named :avatar to upload an avatar
  • Add a hidden_field named :avatar_cache if you want to preserve uploads across form re-renders due to model validation failures

In Haml, this looks something like this:

= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:multipart => true}) do |f| 
  - # ...other form fields 
  = f.label :avatar do
    = f.file_field :avatar 
    = f.hidden_field :avatar_cache

4) Add avatar display and upload to the edit form (optional)

Assuming you have generated custom Devise views in the standard location, and that you are using Haml, this file is something like app/views/devise/registrations/edit.html.haml. You need to:

  • Add :multipart => true to the :html hash passed to form_for.
  • Add an image_tag if you want to display the current avatar
  • Add a file_field named :avatar to upload a new avatar
  • Add a hidden_field named :avatar_cache if you want to preserve uploads across form re-renders due to model validation failures
  • Add a check_box named :remove_avatar if you want to support removing existing avatars.

In Haml, this looks something like this:

= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:method => :put, :multipart => true}) do |f| 
  - # ...other form fields... 
  - if current_user.avatar.url.present?
    = image_tag(current_user.avatar.url) 
    = f.label :remove_avatar do
      = f.check_box :remove_avatar 
  = f.file_field :avatar  
  = f.hidden_field :avatar_cache