Rails没有路由匹配{:action =>" destroy",:controller =>" session"},缺少必需的密钥:[:id]

时间:2018-01-09 23:26:18

标签: ruby-on-rails session authentication

我正在使用具有身份验证的Rails应用程序,并收到错误消息:

没有路由匹配{:action =>" destroy",:controller =>" session"},缺少必需的密钥:[:id]

我在尝试渲染" new"时遇到此错误从会话控制器查看,并且当它应该只是查看New / Create方法时,无法弄清楚它为什么引用destroy方法。下面是我如何设置我的路线,我的控制器,我的模型和我的视图,如果有人可以给我一些指导,我需要检查它并且非常感谢。

路线:

Rails.application.routes.draw do root to: "root#index" resources :users, only: [:new, :create, :index, :show] resources :session, only: [:new, :create, :destroy] resources :pets end

型号:

class User < ApplicationRecord

  PASSWORD_LENGTH = (6..25)
  USERNAME_LENGTH = (5..25)

  validates_presence_of :username
  validates :username, length: USERNAME_LENGTH, uniqueness: true
  validates :password, length: PASSWORD_LENGTH, allow_nil: true

  has_many :pets

  attr_reader :password

  def self.find_from_credentials(username, password)
    user = find_by(username: username)
    return nil unless user
    user if user.is_password?(password)
  end

  def is_password?(password_attempt)
    BCrypt::Password.new(password_digest).is_password?(password_attempt)
  end

  def password=(password)
    @password = password
    self.password_digest = BCrypt::Password.create(password)
  end
end

控制器:

class SessionController < ApplicationController

    before_action :ensure_signed_out, only: [:new, :create]

    def new
        @user = User.new
    end

    def create
        username = user_params[:username]
        password = user_params[:password]

        user = User.find_from_credentials(username, password)

        if user
            sign_in(user)
            flash[:notice] = "#{username} has successfully signed in."
            redirect_to "/"
        else
            flash[:error] = "User not found."
            @user = User.new(username: username)
            render :new
        end
    end

    def destroy
        sign_out
        flash[:notice] = "User signed out."
        redirect_to new_session_path
    end

    private

    def user_params
        params.require(:user).permit(:username, :password)
    end
end

查看:

<h2>Enter your credentials below: </h2>

<%= form_for :user, url: session_path do |f| %>
    <%= f.text_field :username, placeholder: 'Username', required: true %>
    <%= f.password_field :password, placeholder: 'Password', required: true %>
    <%= submit_tag 'Log in' %>
<% end %>


<p> Don't have an account?  <%= link_to 'Sign up here!', new_user_path %></p>

3 个答案:

答案 0 :(得分:1)

备注:如果您正在使用Rails 5.x,那么您希望在视图中使用form_withCheck it out here

我认为问题在于您为表单使用的网址。您已告诉表单向网址提交post请求,该请求会导致session#show操作(session_path),但这并不存在,而您#&# 39;不要发送一个会话实例,这就是为什么它说它错过了id。

您的表单可能看起来像这样(您可能刚刚错过了&#39;:

<h2>Enter your credentials below: </h2>
# you will need to run 'rails routes' in your terminal to find out the exact prefix, but you want the prefix that routes to 'sessions#create'
<%= form_with url: sessions_path do |f| %>
    <%= f.text_field :username, placeholder: 'Username', required: true %>
    <%= f.password_field :password, placeholder: 'Password', required: true %>
    <%= submit_tag 'Log in' %>
<% end %>


<p> Don't have an account?  <%= link_to 'Sign up here!', new_user_path %></p>

答案 1 :(得分:0)

欢迎使用StackOverflow - 很棒的第一个问题!

从顶部开始:当您在resources文件中呼叫routes.rb时,您告诉Rails为标准CRUD制作路由。

现在,根据比你和我更聪明的人 - 也就是将他们的血/汗/泪水倒入Rails的人 - 以及RESTful标准,删除资源 - 在你的情况下,Session - 需要服务器响应DELETE类型的请求(GET / POST / PATCH / PUT / DELETE ......还有更多),

DELETE /sessions/1

Rails映射如下:

match '/sessions/:id' => 'sessions#destroy', :via => :delete

via很重要。请注意,match也可以是delete,我们可以省略via

现在因为我没有您的整个视图文件,很难确定这种情况发生的位置。但是要知道如果你打算删除Session资源,你需要知道它的ID,这就是这个错误试图告诉你的:为该路径生成URL助手(一些Rails魔术)需要一个持久的Session。 / p>

答案 2 :(得分:0)

问题在于表单中使用的URL,因为它应该根据我的路由指向session_index_path。感谢所有回复!