0
votes

I installed paperclip gem to manage users avatars in app but when I trying to change user default avatar it doesn't change. I don't getting any errors and the form is saved correctly. It seems to photo isn't uploaded.

What am I doing wrong? I'm newbie and I cant figure it out.

Model:

class User < ActiveRecord::Base
  has_many :posts
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
         has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/avatar.gif"
         validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end

Controller:

class UsersController < ApplicationController
def create
  @user = User.create( user_params )
end
def update
    @user = User.find(params[:id])
    @user.update_attribute(:avatar, params[:user][:avatar])
end
private

# Use strong_parameters for attribute whitelisting
# Be sure to update your create() and update() controller methods.

def user_params
  params.require(:user).permit(:avatar)
end
end

Edit view:

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <%= devise_error_messages! %>
  <form>
    <div class="form-group">
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, class: "form-control" %>
  </div>

  <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>

  <div class="field">
    <%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
    <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
  </div>

  <div class="field">
    <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: "off", class: "form-control" %>
  </div>
  <%= image_tag @user.avatar.url(:medium) %>
  <%= form_for @user, url: users_path, html: { multipart: true } do |form| %>
  <%= form.file_field :avatar %>
<% end %>
<br>
  <div class="actions">
    <%= f.submit "Update", class: "btn btn-success" %>
  </div>
<% end %>
</div></form>
<p><%= button_to "Delete my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-danger" %></p>

My routes:

new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
           user_password POST   /users/password(.:format)      devise/passwords#create
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                         PATCH  /users/password(.:format)      devise/passwords#update
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
       user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                         PATCH  /users(.:format)               devise/registrations#update
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
              categories GET    /categories(.:format)          categories#index
                  topics GET    /topics(.:format)              topics#index
                         POST   /topics(.:format)              topics#create
               new_topic GET    /topics/new(.:format)          topics#new
              edit_topic GET    /topics/:id/edit(.:format)     topics#edit
                   topic GET    /topics/:id(.:format)          topics#show
                         PATCH  /topics/:id(.:format)          topics#update
                         PUT    /topics/:id(.:format)          topics#update
                         DELETE /topics/:id(.:format)          topics#destroy
                   posts GET    /posts(.:format)               posts#index
                         POST   /posts(.:format)               posts#create
                new_post GET    /posts/new(.:format)           posts#new
               edit_post GET    /posts/:id/edit(.:format)      posts#edit
                    post GET    /posts/:id(.:format)           posts#show
                         PATCH  /posts/:id(.:format)           posts#update
                         PUT    /posts/:id(.:format)           posts#update
                         DELETE /posts/:id(.:format)           posts#destroy
                   users GET    /users(.:format)               users#index
                         POST   /users(.:format)               users#create
                new_user GET    /users/new(.:format)           users#new
               edit_user GET    /users/:id/edit(.:format)      users#edit
                    user GET    /users/:id(.:format)           users#show
                         PATCH  /users/:id(.:format)           users#update
                         PUT    /users/:id(.:format)           users#update
                         DELETE /users/:id(.:format)           users#destroy
                    root GET    /                              categories#index

Record from DB:

  User Load (1.7ms)  SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation [#<User id: 3, email: "[email protected]", encrypted_password: "$2a$10$/oH53eNleU4rc87OSYVtsANt...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2016-03-17 11:10:39", last_sign_in_at: "2016-03-17 11:10:39", current_sign_in_ip: "::1", last_sign_in_ip: "::1", created_at: "2016-03-17 11:10:39", updated_at: "2016-03-17 11:10:39", avatar_file_name: nil, avatar_content_type: nil, avatar_file_size: nil, avatar_updated_at: nil>]>
2
Have you overridden the default devise registrations routes so that they are handled by your UsersController?max
Yes, you can see my routes above, I updated post.Frostbourn
Can you just check your view forms again. You can inspect element into this form from your browser. I see forms inside form. I am not sure about the structure of your form.dp7

2 Answers

1
votes

To add new attributes to the Devise registration you can just override parts of it instead of throwing the baby out with the bathwater:

# app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, [:avatar])
    devise_parameter_sanitizer.permit(:account_update, [:avatar])
  end
end

# config/routes.rb
devise_for :users, controllers: { registrations: "user/registrations" }

Make sure your views are named app/views/users/registrations/new.html.erb and app/views/users/registrations/edit.html.erb.

Just adding more routes is a naive solution - you're badly underestimating how much work the Devise controller actually does. For example your controller does not sign the user in or even check authorization.

0
votes

Thank you for suggestions @max and @Kuba. Everything is working now. I just added following code to application_controller.rb:

class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception
    before_filter :configure_permitted_parameters, if: :devise_controller?

    protected

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