Reputation: 3090
I'm not sure where this error message is coming from. I'm following Hartl's railtutorial but adapting it to my own app. I'm working on chapter 10 and am adding password resets.
When I get the error: After on the server sending the email with the link to reset the password. I then enter the link in my browser and get the following error message:
undefined local variable or method `object'
Extracted source (around line #2):
<% if object.errors.any? %>
This refers to the shared error messages file, which hasn't changed and didn't cause problems before. I'm not sure what to send you to see what could be the cause.
\views\shared_error_messages.html.erb
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
views\passwords_resets\edit.html.erb (the page that is called upon when following the link):
<% provide(:title, 'Reset password') %>
<h1 class="center">Reset password</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
<%= render 'shared/error_messages' %>
<%= hidden_field_tag :email, @user.email %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Update password", class: "btn btn-primary" %>
<% end %>
</div>
</div>
app\controllers\password_resets_controller.rb:
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
def new
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
@user.send_password_reset_email
flash[:info] = "An email is sent to you with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
end
def update
if password_blank?
flash.now[:danger] = "Password can't be blank"
render 'edit'
elsif @user.update_attributes(user_params)
log_in @user
flash[:success] = "Password has been reset."
redirect_to @user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
# Returns true if password is blank.
def password_blank?
params[:user][:password].blank?
end
# Before filters
def get_user
@user = User.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
unless (@user && @user.activated? && @user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
# Checks expiration of reset token.
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
Update: While writing this question I found out that when I remove the line <%= render 'shared/error_messages' %>
from \views\shared_error_messages.html.erb I no longer have the problem and the new view shows correctly. It then works correctly in that I can change the password. However, the error messages then don't show up anymore (e.g., when password and password confirmation don't match). What to do?
Upvotes: 0
Views: 2883
Reputation: 899
You have to pass an object to the error messages template when you render it. Your call to render the error messages template should now include object: f.object
, like so:
<%= render "shared/error_messages", object: f.object %>
Upvotes: 1
Reputation: 146
Your partial doesnt know anything about "object". You have to pass @user object to the partial:
<%= render 'shared/error_messages', locals: {object: @user %>
Upvotes: 0