Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

before_action in user controller rendering error: NoMethodError in Users#show

I am following Michael Hartl's Rails guide (on chapter 9). When I try to access the page corresponding the the user's profile, the browser displays the following error messages:

 NoMethodError in Users#show

Showing /home/jonathan/Desktop/railsTut/sample_app/app/views/users/show.html.erb where line #1 raised:

undefined method `name' for nil:NilClass

Extracted source (around line #1):

1: <% provide(:title, @user.name) %>
2: <div class="row">
3:   <aside class="span4">
4:     <section>

Rails.root: /home/jonathan/Desktop/railsTut/sample_app

Here is my users_controller.rb

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:edit, :update]

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])    # Not the final implementation!
    if @user.save
     sign_in @user
     flash[:success] = "Welcome to the Sample App!"
     redirect_to @user
    else
      render 'new'
    end
  end

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

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
         flash[:success] = "Profile updated"
         sign_in @user
         redirect_to @user
      else
           render 'edit'
      end
    end

  def destroy
 User.find(params[:id]).destroy
    flash[:success] = "User destroyed."
    redirect_to users_url
    end

private

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


  # Before filters

  def signed_in_user
    unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
    end
 end
end

The page loads fine without the line:

before_action :signed_in_user, only: [:edit, :update]

But with it's inclusion things go wrong and I can't figure out why.

Also, here is the routes.rb

SampleApp::Application.routes.draw do
  resources :users
  resources :sessions, only: [:new, :create, :destroy]

  root to: 'static_pages#home'

 match '/signup',  to: 'users#new'
  match '/signin',  to: 'sessions#new'
  match '/signout', to: 'sessions#destroy', via: :delete

  match '/help',    to: 'static_pages#help'
  match '/about',   to: 'static_pages#about'
  match '/contact', to: 'static_pages#contact'

end

Any help is appreciated!

like image 781
i_trope Avatar asked Jul 23 '13 10:07

i_trope


4 Answers

If indeed Hurman's answer solved your problem, the reason is because you are running an older version (i.e. <4.0.0) of rails. before_filter was renamed in this version to before_action (https://github.com/rails/rails/commit/9d62e04838f01f5589fa50b0baa480d60c815e2c), more information in Rails 4: before_filter vs. before_action

like image 95
frbl Avatar answered Oct 25 '22 12:10

frbl


I had the same problem using 4.1.6. The problem is that you have defined the before_action as private, I don't know why but this type of visibility messes with the controller's before_action load in Rails. So just bring signed_in_user outside that area and it should start working again.

Hope this helps!

like image 31
WyrmxD Avatar answered Oct 25 '22 14:10

WyrmxD


Instead of Before Action in Users_controller try before filter So your code looks like this:

before_filter :signed_in_user, only: [:edit, :update]

I had the exact same error!

like image 37
Hurman Gul Avatar answered Oct 25 '22 14:10

Hurman Gul


Further to @Hurman Gul's answer, I'll hopefully give you some details about why you're seeing this problem...


Your Controller Is Performing An Action On A Non-Existent Variable

The error you have is because one of your actions is trying to perform an action on a variable which is either not set, or has no content (is nil). The error basically means that you're trying to call the ".name" part of a variable, where it doesn't exist

undefined method `name' for nil:NilClass

Extracted source (around line #1):

1: <% provide(:title, @user.name) %>
2: <div class="row">
3:   <aside class="span4">
4:     <section>

Rails.root: /home/jonathan/Desktop/railsTut/sample_app

This basically means that in your view, you're trying to load @user.name, when @user probably doesn't exist. The way I'd recommend fixing this is to initially apply some logic to your view:

#app/views/users/show.html.erb
<% unless defined?(@user) %>
    Sorry, we could not find your user!
<% else %>

 your code

<% end %>
like image 23
Richard Peck Avatar answered Oct 25 '22 12:10

Richard Peck