Когда я создаю User в своем приложении Rails, я получаю следующую ошибку ...

NoMethodError (undefined method `collation' for nil:NilClass)

Я бился головой о стену с помощью рельсов, пытаясь понять, в чем проблема.

Я не совсем уверен, что не так с моим кодом, так как он в значительной степени шаблонный, как вы можете видеть ниже ...

< Сильный > user.rb

class User < ApplicationRecord
  has_secure_password

  before_create do
    self.username = 'user-' + SecureRandom.hex(8)
  end

  validates :email, presence: true, uniqueness: true, length: { within: 4..255 }
  validates :username, uniqueness: true, length: { is: 13 }
  validates :password, presence: true, uniqueness: true, length: { within: 8..255 }
end

< Сильный > user_controller.rb

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  def index
    @users = User.all
  end

  def show; end

  def new
    @user = User.new
  end

  def edit; end

  def create
    @user = User.new(user_params)

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
      else
        format.html { render :new }
      end
    end
  end

  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
  end

  def destroy
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
    end
  end

  private

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

  def user_params
    params.fetch(:user).permit(:username, :email, :password, :password_confirmation)
  end
end

_form.html.erb

<%= form_for(@user, local: true) do |form| %>
  <div class="field">
    <%= form.label :email %>
    <%= form.text_field :email %>
  </div>

  <div class="field">
    <%= form.label :password %>
    <%= form.password_field :password %>
  </div>

  <div class="field">
    <%= form.label :password_confirmation, 'Password Confirmation' %>
    <%= form.password_field :password_confirmation %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Я также изменил кодировку в базе данных, похоже, ничего не работает.

< Сильный > UPDATE Я не совсем уверен, что было не так, я вернулся к своей «первоначальной фиксации» проекта и восстановил все, и он работает нормально, он использует тот же код. Я отмечу это как решенное, но у меня нет правильного решения, кроме как восстановить.

0
Anmol Brar 10 Фев 2020 в 00:29

3 ответа

Лучший ответ

Я не совсем уверен, что было не так, я вернулся к своей «первоначальной фиксации» проекта и восстановил все, и он работает нормально, он использует тот же код. Я отмечу это как решенное, но у меня нет правильного решения, кроме как восстановить.

0
Anmol Brar 10 Фев 2020 в 00:52

Он говорит вам, в чем ошибка. Вы звоните .collation о чем-то, я думаю, @user. Журнал скажет вам, какая строка вызывает ошибку. Что эта линия выглядит как линия?

Например, если ошибка содержала такую строку:

app/views/layouts/application.html.erb:16

Тогда что-то вроде @user.collation будет вызвано там. Но, учитывая, что вторая часть ошибки говорит о nil:NilClass, это означает, что @user не установлен.

Обновить

Так что эта строка указывает на ваш метод create, в котором есть ошибка. Это должно быть User.create(user_params), а не User.new(user_params). Хотя после этого вы звоните .save, так что это должно сработать.

Также, возможно, сделайте обратный вызов after_create и измените его следующим образом:

after_create do
  update(:username, "user-#{SecureRandom.hex(8)}"
end

Нет недостатка в этом, и это может раскрыть то, что происходит. before_create Я считаю себя очень коварным.

0
okay56k 10 Фев 2020 в 00:26
validates :password, presence: true, uniqueness: true, length: { within: 8..255 }

Здесь удалите uniqueness: true

Вы не хотите, чтобы пароль был уникальным, и, насколько я знаю, если вы используете has_secure_password, гем bcrypt сохранит дайджест пароля пользователя в вашей базе данных, что сделает его почти невозможно проверить, идентичны ли пароли двух пользователей.

0
printfinn 30 Мар 2020 в 10:06