When I create User in my Rails app I get the following error...
NoMethodError (undefined method `collation' for nil:NilClass)
I've been banging my head on a wall with rails trying to figure out what the problem is.
I'm not quite sure what is wrong with my code, as it is pretty much boilerplate as you can see below...
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 %>
I have changed the encoding on the database as well, nothing seems to be working.
UPDATE I'm not quite sure what was wrong, I reverted to my 'initial commit' of the project and regenerated everything, and it works fine, it uses the same code. I'll mark this as solved, but I have no proper solution other than regenerating.
validates :password, presence: true, uniqueness: true, length: { within: 8..255 }
Here, remove uniqueness: true
You don't want to force a password to be unique, and as far as I know, if you use has_secure_password
, bcrypt
gem will save a digest of the user password to your database, making it almost impossible to verify if two users' passwords are the identical.
As said printfinn you have to remove uniqueness validation on password. His answer should be the accepted one.
I had the same error message as you.
I was trying to validate a field (presence and uniqueness) with a mistake in the name. The name was the name of a function. Rails could validate the presence, but not the uniqueness.
It's telling you what the error is. You're calling .collation
on something—I'd guess on @user
. The log will tell you which line is causing the error. What does that line look line?
For example, if the error contained a line like this:
app/views/layouts/application.html.erb:16
Then something like @user.collation
would be called there. But given that the second part of the error says on nil:NilClass
it means that @user
isn't set.
Update
So that line points to your create
method which has an error in it. It should be User.create(user_params)
, not User.new(user_params)
. Although, you are calling .save
afterwards, so it should work.
Also, maybe make the callback after_create
and change it to this:
after_create do
update(:username, "user-#{SecureRandom.hex(8)}"
end
No downside to that, and it might expose what's going on. before_create
I find to be real treacherous.
I'm not quite sure what was wrong, I reverted to my 'initial commit' of the project and regenerated everything, and it works fine, it uses the same code. I'll mark this as solved, but I have no proper solution other than regenerating.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.