InstanceVariableAssumption: UsersController assumes too much for instance variable '@user'

2.4k Views Asked by At

I'm following Michael Hartl tutorial Rails course. On chapter 7, I run Reek on UsersController and I got this following warning:

app/controllers/users_controller.rb -- 1 warning:
1:InstanceVariableAssumption: UsersController assumes too much for instance variable '@user' [https://github.com/troessner/reek/blob/master/docs/Instance-Variable-Assumption.md]

Here is my code:

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new user_params
    if @user.save
      flash[:success] = t "welcome_to_app"
      redirect_to @user
    else
      render "new"
    end
  end

  def show
    @user = User.find_by id: params[:id]

    return if @user
    flash[:danger] = t "not_exist_user"
    redirect_to root_path
  end

  private

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

Kindly explain why I got this error InstanceVariableAssumption and how to fix this.

3

There are 3 best solutions below

0
On BEST ANSWER

We could use like this:

attr_reader :user, :users

Then all @user, @users can be written like user or users.

0
On

That looks like one of the smells that reek recommends disabling on the GitHub page. According to this bug report filed on the project, it appears this is just due to rails making use/encouraging patterns that reek doesn't like by default.

0
On

Instance Variable Assumption says:

Classes should not assume that instance variables are set or present outside of the current class definition.

Well, this is where Convention over configuration comes in Rails. Rails has its own way of doing things, and the class: UsersController has a dependency upon the class: User.

The variable: @user is an instance variable defined in UsersController, but this is an object of class User. And this is how the things are done in Rails, and you will find it everywhere.

Just assume that this isn't perfect according to Reek gem, but this is how the things are done in Ruby on Rails.