title: Why does the order of the before_actions declaration matter?
body: <p>I am working through Hartl's Ruby on Rails Tutorial. When doing Chapter 11, I updated the before_actions in the UserController and did not think the order mattered. So mine looked like this:</p>
  
  <pre><code>class UsersController &lt; ApplicationController
    before_action :correct_user,   only: [:edit, :update]
    before_action :admin_user,     only: :destroy
    before_action :signed_in_user,
              only: [:index, :edit, :update, :destroy, :following, :followers]
  </code></pre>
  
  <p>His looked like this:</p>
  
  <pre><code>class UsersController &lt; ApplicationController
    before_action :signed_in_user,
              only: [:index, :edit, :update, :destroy, :following, :followers]
    before_action :correct_user,   only: [:edit, :update]
    before_action :admin_user,     only: :destroy
  </code></pre>
  
  <p>The only difference is the order of the statements.</p>
  
  <p>When I run rspec on mine, I get four errors. But when I change the order, there are none. I don't see any dependence on the order of the declarations. I would like to know why the order matters.</p>
  
  <p>That's my question... Here is more information about the code I am running. </p>
  
  <p>Because I'm at the end of the book, there is a lot of code, so I will try to include the parts that I think could be relevant.</p>
  
  <p>Two of the actions listed in the declarations are defined at the end of the same class:</p>
  
  <pre><code>class UsersController &lt; ApplicationController
  
    before_action :correct_user,   only: [:edit, :update]
    before_action :admin_user,     only: :destroy
    before_action :signed_in_user,
              only: [:index, :edit, :update, :destroy, :following, :followers]
  
  .
  .
  .
    private
  
    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
  
    # Before filters
  
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end
  
    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end
  end
  </code></pre>
  
  <p>The third one is defined in the SessionsHelper which is included in the ApplicationController, the parent class of UsersController:</p>
  
  <pre><code>class ApplicationController &lt; ActionController::Base
    protect_from_forgery with: :exception
    include SessionsHelper
  end
  
  module SessionsHelper
  .
  .
  .
    def current_user=(user)
      @current_user = user
    end
  
    def current_user
      remember_token = User.digest(cookies[:remember_token])
      @current_user ||= User.find_by(remember_token: remember_token)
    end
  
    def current_user?(user)
      user == current_user
    end
  
    def signed_in_user
      unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
      end
    end
  
    def signed_in?
      !current_user.nil?
    end
  .
  .
  .
  </code></pre>
  
  <p>Here is the result if running rspec with the code ordered the way I did it:</p>
  
  <pre><code>&gt;rspec spec
  .............................................................................F.
  ....FF.............................................F...........................
  .............
  
  Failures:
  
    1) Authentication authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page
       Failure/Error: expect(page).to have_title('Edit user')
         expected #has_title?("Edit user") to return true, got false
       # ./spec/requests/authentication_pages_spec.rb:68:in `block (6 levels) in &lt;top (required)&gt;'
  
    2) Authentication authorization for non-signed-in users in the Users controller visiting the edit page 
       Failure/Error: it { should have_title('Sign in') }
         expected #has_title?("Sign in") to return true, got false
       # ./spec/requests/authentication_pages_spec.rb:117:in `block (6 levels) in &lt;top (required)&gt;'
  
    3) Authentication authorization for non-signed-in users in the Users controller submitting to the update action 
       Failure/Error: specify { expect(response).to redirect_to(signin_path) }
         Expected response to be a redirect to &lt;http://www.example.com/signin&gt; but was a redirect to &lt;http://www.example.com/&gt;.
         Expected "http://www.example.com/signin" to be === "http://www.example.com/".
       # ./spec/requests/authentication_pages_spec.rb:122:in `block (6 levels) in &lt;top (required)&gt;'
  
    4) User pages as admin user should not be able to delete it's own account 
       Failure/Error: expect { delete user_path(admin) }.not_to change(User, :count)
       NoMethodError:
         undefined method `admin?' for nil:NilClass
       # ./app/controllers/users_controller.rb:95:in `admin_user'
       # ./spec/requests/user_pages_spec.rb:79:in `block (5 levels) in &lt;top (required)&gt;'
       # ./spec/requests/user_pages_spec.rb:79:in `block (4 levels) in &lt;top (required)&gt;'
  
  Finished in 8.84 seconds
  171 examples, 4 failures
  
  Failed examples:
  
  rspec ./spec/requests/authentication_pages_spec.rb:67 # Authentication authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page
  rspec ./spec/requests/authentication_pages_spec.rb:117 # Authentication authorization for non-signed-in users in the Users controller visiting the edit page 
  rspec ./spec/requests/authentication_pages_spec.rb:122 # Authentication authorization for non-signed-in users in the Users controller submitting to the update action 
  rspec ./spec/requests/user_pages_spec.rb:78 # User pages as admin user should not be able to delete it's own account 
  </code></pre>
  
  <p>Here are the failing tests in the authentication_pages_spec.rb:</p>
  
  <pre><code>describe "Authentication" do
    subject { page }
  .
  .
  .
    describe "authorization" do
  
      describe "for non-signed-in users" do
        let(:user) { FactoryGirl.create(:user) }
  
        describe "when attempting to visit a protected page" do
          before do
            visit edit_user_path(user)
            sign_in(user)
          end
  
          describe "after signing in" do
  
            it "should render the desired protected page" do
              expect(page).to have_title('Edit user')
            end
  
  .
  .
  .
        end
  .
  .
  .
        describe "in the Users controller" do
  
          describe "visiting the edit page" do
            before { visit edit_user_path(user) }
            it { should have_title('Sign in') }
          end
  
          describe "submitting to the update action" do
            before { patch user_path(user) }
            specify { expect(response).to redirect_to(signin_path) }
          end
          describe "visiting the user index" do
            before { visit users_path }
            it { should have_title('Sign in') }
          end
  
          describe "visiting the following page" do
            before { visit following_user_path(user) }
            it { should have_title('Sign in') }
          end
  
          describe "visiting the followers page" do
            before { visit followers_user_path(user) }
            it { should have_title('Sign in') }
          end
  
        end
      end
  </code></pre>
  
  <p>Just to be complete, let me add that if I change the order of the before_action declarations to this:</p>
  
  <pre><code>  before_action :signed_in_user,
                  only: [:index, :edit, :update, :destroy, :following, :followers]
    before_action :correct_user,   only: [:edit, :update]
    before_action :admin_user,     only: :destroy
  </code></pre>
  
  <p>All of the tests pass:</p>
  
  <pre><code>&gt;rspec spec
  ..............................................................
  ..............................................................
  ...............................................
  
  Finished in 8.82 seconds
  171 examples, 0 failures
  </code></pre>
  
  <p>The code seems to work perfectly in the browser either way. The order of the declarations only affects the result of the tests. It took me a while to find this problem by going back over Hartl's code and making sure mine exactly reflected his. I found this order difference after a while and made the change, and suddenly my tests all passed. I've switched the order back and forth several times to make sure it is the order and only the order that is changing and that is making the difference. I'd like to understand so I'm not caught on a similiar problem when I am writing my own code rather than copying someone else's code.</p>