marcamillion
marcamillion

Reputation: 33755

Why does my Registrations#Update devise action not update all attributes in my `User` model?

This is my views/devise/registrations/edit.html.erb:

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: "edit-user-form m-t" }) do |f| %>
      <%= f.error_notification %>    
        <div class="form-group">
          <%= f.input_field :email, required: true, autofocus: true %>
        </div>

        <div class="form-group">
          <%= f.input_field :current_password, hint: "we need your current password to confirm your changes", placeholder: "current password", required: true %>
        </div>

        <div class="form-group">
          <%= f.input_field :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", placeholder: "new password", required: false %>
        </div>
        <div class="form-group">
          <%= f.input_field :password_confirmation, placeholder: "confirm new password", required: false %>
        </div>

        <div class="form-group">
            <%= f.association :school, collection:  School.where(school_type: [:college, :university]), prompt: "Choose a school", class: 'col-lg-4 form-control', label: false %>
        </div>
      </div>

      <div class="form-group">
          <div class="col-lg-12 text-center">
            <%= f.button :submit, "Update", class: "btn btn-lg edit-account-update-button" %>
          </div>
      </div>

    <% end %>

And this is my ApplicationController:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?
  check_authorization :unless => :devise_controller?

  rescue_from CanCan::AccessDenied do |exception|
    respond_to do |format|
      format.json { head :forbidden }
      format.html { redirect_back(fallback_location: root_path, flash: { danger: exception.message }) }
    end
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:account_update, keys: [:avatar, :avatar_cache, :remove_avatar, :school_id])
  end
end

The issue though is that it isn't updating the record, here is the log from that operation:

Started PUT "/users" for ::1 at 2016-11-02 19:22:59 -0500
Processing by DeviseInvitable::RegistrationsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Xo445XVpElgDmfcjywZKEbsXIqZR/2Wgw==", "user"=>{"remove_avatar"=>"0", "avatar_cache"=>"", "email"=>"[email protected]", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "school_id"=>"3"}, "commit"=>"Update"}
  User Load (4.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 7], ["LIMIT", 1]]
  User Load (9.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 7], ["LIMIT", 1]]
   (0.7ms)  BEGIN
  SQL (4.2ms)  UPDATE "users" SET "updated_at" = $1, "avatar" = $2 WHERE "users"."id" = $3  [["updated_at", 2016-11-03 00:22:59 UTC], ["avatar", "a1.jpg"], ["id", 7]]
   (0.8ms)  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 139ms (ActiveRecord: 19.1ms)

Note that the school_id is set in the params, so we know it properly accepts the input from the form. But the SQL UPDATE statement, doesn't include school_id, so it doesn't actually save that info to the DB.

Also note that there are no unpermitted params messages in the log.

What could be causing this?

Edit 1

This is the School.rb model:

class School < ApplicationRecord
  has_many :users

  enum school_type: { high_school: 0, college: 1, university: 2 }
end

This is the User.rb model:

class User < ActiveRecord::Base
  belongs_to :school    
end

Upvotes: 0

Views: 272

Answers (1)

Akash Agarwal
Akash Agarwal

Reputation: 2520

The problem was that your devise model User was inheriting ActiveRecord::Base instead of ApplicationRecord which is an abstract class in Rails 5. With the inheritance of latter, most of the gems which deal with models can and do modify the code of ActiveRecord::Base in their own context without affecting other models, which isn't possible if you inherit the former.

Source: Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?

Upvotes: 1

Related Questions