Daniel Friis
Daniel Friis

Reputation: 484

Precompiling assets locally broke my app

I am a newbie programmer following the Michael Hartl tutorial.

I was about to finish chapter 9, which adds the functionality to view all users at the site and delete individual ones with an admin functionality.

All specs were passing and everything working as expected, locally. However, when I tested the site at Heroku the index of the users looked different from the local index.

I tried to precompile assets before pushing to Heroku, which fixed to problem. However, now the functionality to delete users didn't work. Instead of deleting the user, I was forwarded to that user. The same happened to the local version. Furthermore, I noticed that clicking the sign-out link returned an error:

No route matches [GET] "/signout"

All my specs are still passing which only makes it more of a mystery to me! I suspect it's a problem with how assets are compiled, but as a rails newbie, it feels like looking for the needle in a haystack so any help is welcome.

routes.rb

Hooter::Application.routes.draw do

  resources :users
  resources :sessions, only: [:new, :create, :destroy]

  root to: 'static_pages#home'
  match '/help', to: 'static_pages#help'
  match '/about', to: 'static_pages#about'
  match '/contact', to: 'static_pages#contact'
  match '/signup', to: 'users#new'
  match '/signin', to: 'sessions#new'
  match '/signout', to: 'sessions#destroy', via: :delete

user_controller.rb

class UsersController < ApplicationController
  before_filter :signed_in_user, only: [:index, :edit, :update, :destroy]
  before_filter :correct_user, only: [:edit, :update]
  before_filter :admin_user, only: :destroy

  def new
    @user = User.new
  end

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

  def index
    @users = User.paginate(page: params[:page])
  end

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

  def edit
  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 signed_in_user
        unless signed_in?
          store_location
          redirect_to signin_url, notice: "Please sign in."
        end
      end

      def correct_user
        @user = User.find(params[:id])
        redirect_to(root_path) unless current_user?(@user)
      end

      def admin_user
        redirect_to(root_path) unless current_user.admin?
      end
end

_header.html.erb

<header class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container">
      <%= link_to "hooter", root_path, id: "logo" %>
      <nav>
        <ul class="nav pull-right">
          <li><%= link_to "Home",    root_path %></li>
          <li><%= link_to "Help",    help_path %></li>
            <% if signed_in? %>
                <li><%= link_to "Users", users_path %></li>
                <li id="fat-menu" class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                        Account <b class="caret"></b>
                    </a>
                    <ul class="dropdown-menu">
                        <li><%= link_to "Profile", current_user %></li>
                        <li>
                            <%= link_to "Settings", edit_user_path(current_user) %>
                        </li>
                        <li class="divider"></li>
                        <li>
                        <%= link_to "Sign out", signout_path, method: "delete" %>
                        </li>
                    </ul>
                </li>
            <% else %>
                <li><%= link_to "Sign in", signin_path %></li>
            <% end %>
        </ul>
      </nav>
    </div>
  </div>
</header>

application.js

//= require jquery_ujs
//= require jquery
//= require bootstrap
//= require_tree .

application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag    "application", media: "all" %>
    <%= javascript_include_tag "application" %>
    <%= csrf_meta_tags %>
    <%= render 'layouts/shim' %>    
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
          <% flash.each do |key, value| %>
            <div class="alert alert-<%= key %>"><%= value %></div>
          <% end %>
          <%= yield %>
          <%= render 'layouts/footer' %>
          <%= debug(params) if Rails.env.development? %>
        </div>
  </body>
</html>

Upvotes: 1

Views: 235

Answers (3)

Daniel Friis
Daniel Friis

Reputation: 484

With help from the commenters and outsiders I managed to fix the problem.

First of all I deleted the public/assets folder, which enable Heroku to do the compiling.

Then I moved //= require bootstrap below my jquery import as such:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

Upvotes: 0

Dipak Panchal
Dipak Panchal

Reputation: 6036

Use this application.js file and try it

application.js

//= require jquery
//= require jquery_ujs
//= require_tree .

in your book that you are reading, see Listing 8.25.

Source : http://ruby.railstutorial.org/book/ruby-on-rails-tutorial?version=3.2#sec-signin_upon_signup

Upvotes: 0

Adrien Coquio
Adrien Coquio

Reputation: 4930

This issue No route matches [GET] "/signout" is relevant because you effectively do not accept GET request on /signout, from your routes definition, it should be DELETE verb.

This may happen because of missing javascript library, could you check if some are missing ?

Upvotes: 1

Related Questions