Закрытый метод update_without_password для nil:NilClass

Я следую этому уроку по аутентификации cancancan и особенно хочу, чтобы администраторы обновляли пользователей без пароля. Я также видел это предложение, но не уверен, как адаптировать его в свой собственный код. Когда я нажимаю кнопку обновить, он говорит: "NoMethodError в UsersController#update" закрытый метод update_without_password, вызванный для nil:NilClass

Мое приложение возвращает все параметры пользователя, поэтому я не понимаю, что здесь происходит. Все еще очень плохо знакомы с рельсами - дайте мне знать, если вам нужна дополнительная информация. Заранее спасибо!

ПОЛЬЗОВАТЕЛЬСКИЙ КОНТРОЛЛЕР

class UsersController < ApplicationController
before_filter :authenticate_user!



 def update
  if user_params[:password].blank?
    user_params.delete(:password)
    user_params.delete(:password_confirmation)
  end


  successfully_updated = if needs_password?(@user, user_params)
                           @user.update(user_params)
                         else
                           @user.update_without_password(user_params)
                         end
 respond_to do |format|
    if successfully_updated
      format.html { redirect_to @user, notice: 'User was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: 'edit' }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end


  rescue ActiveRecord::RecordNotFound
    respond_to_not_found(:js, :xml, :html)
  end


private
def needs_password?(user, params)
  params[:password].present?
end

def update_without_password(user_params)
  user.update_without_password(user_params)
end



def user_params
        params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :name, :role_id, :accepted)
end

РЕДАКТИРОВАТЬ ФОРМУ

<h3><%= @user == @current_user ? "Your Account Settings" : "Edit User" %></h3>

<%= form_for(@user, :html => { :method => :put }) do |f| %>
 <p><%= f.label :first_name %></p>
 <p><%= f.text_field :first_name %></p>

 <p><%= f.label :last_name %></p>
 <p><%= f.text_field :last_name %></p>

 <p><%= f.label :email %></p>
 <p><%= f.text_field :email %></p>
  <% if can? :read, Role %>
 <%= collection_select(:user, :role_id, Role.all, :id, :name, {prompt: true}) %>
  <% end %>
 <p><%= f.submit "Update" %></p>
<% end %>

Что мне здесь не хватает? Пожалуйста, дайте мне знать, если должны предоставить что-нибудь еще. Спасибо!!

1 ответ

Решение

Мне кажется, что вы видите эту ошибку, потому что @user не создается в update метод. Вам нужно установить @user к примеру вашего User модель. Не видя ваше полное приложение, я не могу знать наверняка, но вы должны иметь доступ к :id в хэше params, позволяя настроить @user делать что-то вроде этого:

@user = User.find(params[:id])

Поскольку вы копаетесь в CanCan, я настоятельно рекомендую вам прочитать их документацию для load_and_authorize_resource метод. Вы используете его в своих контроллерах для СУХОГО повторяющегося кода, который загружает объект или коллекцию, с которой вы хотите работать. Он использует имя контроллера, в котором вы находитесь, и :id значение от params автоматически создавать экземпляр вашего ресурса. Итак, в вашем show, edit, а также update методы, это будет экземпляр единственного числа @user объект в вашем UsersControllerи в вашем index метод, он будет создавать экземпляр коллекции @users,

FWIW, вы можете спросить, почему вы не видите NoMethodError всплывать на if needs_password?(@user, user_params) линия. Даже если @user используется там, если вы посмотрите на определение вашего needs_password? метод, он требует user аргумент, но на самом деле не использует его, поэтому он не будет жаловаться на тот факт, что @user ноль, когда это называется. Тем не менее, в этой строке @user.update_without_password(user_params)Вы отправляете update_without_password метод / сообщение для @user переменная, которая является nil,

Надеюсь, это поможет!

Другие вопросы по тегам