路由错误 - 尝试访问new_deck_path时没有路由匹配

时间:2013-05-29 04:15:57

标签: ruby-on-rails-3 rails-routing

链接到new_deck_path时收到以下错误

No route matches {:action=>"show", :controller=>"decks", :id=>#<Deck id: nil, name: nil, created_at: nil, updated_at: nil, user_id: 3>}

我的服务器显示以下内容:

Started GET "/decks/new" for 127.0.0.1 at 2013-05-29 00:08:01 -0400
Processing by DecksController#new as HTML
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 3]]
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 3]]
  Rendered decks/new.html.erb within layouts/application (2.6ms)
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 3]]
Completed 500 Internal Server Error in 29ms

ActionController::RoutingError (No route matches {:action=>"show", :controller=>"decks", :id=>#<Deck id: nil, name: nil, created_at: nil, updated_at: nil, user_id: 3>}):
  app/views/layouts/application.html.erb:51:in `_app_views_layouts_application_html_erb__3049462299863220867_2194729200'


  Rendered /usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.9ms)

为什么错误告诉我没有路线匹配?当我运行rake路线时,路线出现了。另外,为什么“show”动作会显示在错误中?正在运行的操作是#new,我可以根据服务器中的输出确认这一点。我想简单地允许用户点击“New deck”并转到New Deck页面。我无法弄清楚这里发生了什么......

application.html.erb

  <body>

    <div class="container-narrow">

      <div class="masthead">
        <ul class="nav nav-pills pull-right">
                <% if signed_in? %>
                    <% if current_page? root_path %>
                    <li class=""><%= link_to "My decks", decks_path %></li>
                    <li class=""><%= link_to "Sign out", session_path, method: :delete %></li>
                    <% elsif current_page? decks_path %>
                  <li class="active"><%= link_to "New Deck", new_deck_path %></li>
                    <li class=""><%= link_to "Sign out", session_path, method: :delete %></li>
                    <% elsif current_page? deck_path(@deck) %>
                    <li class="active"><%= link_to "View decks", decks_path %></li>
                    <li class="active"><%= link_to "Add card", new_deck_card_path(@deck) %></li>
                    <li class=""><%= link_to "Sign out", session_path, method: :delete %></li>
                    <% else %>
                    <li class="active"><%= link_to "Back to #{@deck.name}", deck_path(@deck) %></li>
                    <li class=""><%= link_to "Sign out", session_path, method: :delete %></li>
                    <% end %>
                <% else %>
                <li><%= link_to "Sign in with Twitter", "/auth/twitter" %></li>
          <li><%= link_to "Sign in", new_session_path %></li>
          <li><%= link_to "Sign up", new_user_path %></li>
                <% end %>
        </ul>
        <a href="<%= root_path %>"><h3 class="muted offset1">Flashy</h3></a>
      </div>

      <hr>

     <%= yield %>
</body>

的routes.rb

Flashy::Application.routes.draw do

  match "/auth/:provider" => redirect("http://#{DOMAIN_NAME}/auth/#{:provider}"), :as => :signin
  match '/auth/:provider/callback' => 'sessions#create'
  match '/signout' => 'sessions#destroy', :as => :signout

  resource :session, only: [:new, :create, :destroy]
  resources :users, only: [:new, :create]

  resources :decks do
    resources :cards, except: :index
  end

  root :to => "homes#index"

end

decks_controller.rb

class DecksController < ApplicationController
  before_filter :authenticate

  def index
    @decks = current_user.decks
  end

  def new
    @deck = current_user.decks.new
  end

  def show
    @deck = find_deck
    @cards = @deck.cards
  end

  def create
    @deck = current_user.decks.new(params[:deck])
    @deck.save
    redirect_to decks_path
  end

  def edit
    @deck = find_deck
  end

  def update
    @deck = find_deck
    @deck.update_attributes(params[:deck])
    # redirect_to @deck <-- Polymorphic path
    redirect_to deck_path(@deck)
  end

  def destroy
    @deck = find_deck
    @deck.destroy
    redirect_to decks_path
  end

  private

    def find_deck
      current_user.decks.find(params[:id])
    end

end

rake routes

          root        /                                        homes#index
        signin        /auth/:provider(.:format)                :controller#:action
                      /auth/:provider/callback(.:format)       sessions#create
       signout        /signout(.:format)                       sessions#destroy
       session POST   /session(.:format)                       sessions#create
   new_session GET    /session/new(.:format)                   sessions#new
               DELETE /session(.:format)                       sessions#destroy
         users POST   /users(.:format)                         users#create
      new_user GET    /users/new(.:format)                     users#new
    deck_cards POST   /decks/:deck_id/cards(.:format)          cards#create
 new_deck_card GET    /decks/:deck_id/cards/new(.:format)      cards#new
edit_deck_card GET    /decks/:deck_id/cards/:id/edit(.:format) cards#edit
     deck_card GET    /decks/:deck_id/cards/:id(.:format)      cards#show
               PUT    /decks/:deck_id/cards/:id(.:format)      cards#update
               DELETE /decks/:deck_id/cards/:id(.:format)      cards#destroy
         decks GET    /decks(.:format)                         decks#index
               POST   /decks(.:format)                         decks#create
      new_deck GET    /decks/new(.:format)                     decks#new
     edit_deck GET    /decks/:id/edit(.:format)                decks#edit
          deck GET    /decks/:id(.:format)                     decks#show
               PUT    /decks/:id(.:format)                     decks#update
               DELETE /decks/:id(.:format)                     decks#destroy

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  def current_user
    if cookies[:user_id]
      user_id = cookies.signed[:user_id]
      User.find_by_id(user_id)
    else
      User.find(session[:user_id]) if session[:user_id]
    end
  end
  helper_method :current_user
end

sessions_controller.rb

class SessionsController < ApplicationController
  def new
  end

  def create
    if !request.env["omniauth.auth"].nil?
      auth = request.env["omniauth.auth"]
      user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
      session[:user_id] = user.id
    else
      user = User.find_by_email(params[:session][:email])
      sign_in(user)
      cookies.signed[:user_id] = user.id
    end
    redirect_to decks_path
  end

  def destroy
    if cookies[:user_id].nil?
      session[:user_id] = nil
    else
      cookies.delete(:user_id)
    end
    redirect_to root_path, notice: "Signed out!"
  end
end

2 个答案:

答案 0 :(得分:0)

我认为这会导致错误,对吧?

<li class="active"><%= link_to "Back to #{@deck.name}", deck_path(@deck) %></li>

您尝试使用nil id

链接显示操作

答案 1 :(得分:0)

@deck正在生成错误,因为它尚未保存。我通过在视图中而不是在布局中放置content_for辅助方法来解决问题。

<% content_for :nav do %>
  <li class="active"><%= link_to "New Deck", new_deck_path %></li>
<% end %>


      <div class="masthead">
        <ul class="nav nav-pills pull-right">
                <% if signed_in? %>
                                     <%= yield :nav %>
                <% else %>
                <li><%= link_to "Sign in with Twitter", "/auth/twitter" %></li>
          <li><%= link_to "Sign in", new_session_path %></li>
          <li><%= link_to "Sign up", new_user_path %></li>
                <% end %>
        </ul>
        <a href="<%= root_path %>"><h3 class="muted offset1">Flashy</h3></a>
      </div>