“缺少必需的密钥” - Ruby on Rails

时间:2017-06-06 22:31:52

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

我有以下控制器名为Login:

class LoginController < ApplicationController
  skip_before_action :verify_authenticity_token
  protect_from_forgery
  before_action :require_user
  helper_method :current_user

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    rescue ActiveRecord::RecordNotFound
  end

  def require_user
    redirect_to login_path unless current_user
  end

  def show

  end

  def new
    if session[:user]
      @user = User.find(session[:user])
    end
  end

  def destroy
    reset_session
    redirect_to "/login/acesso", notice: "Você foi deslogado"
  end

  def create
    user = User.validate(login_params[:email], login_params[:senha])
    if user
      session[:user] = user.id
      redirect_to "/home/inicio", notice: "login feito com sucesso"
    else
      redirect_to "/login/acesso", notice: "Dados incorretos"
    end
  end

  private

  def login_params
    params.require(:login).permit(:email, :senha)
  end
end

这是我的路线:

Rails.application.routes.draw do

  root 'login#new'
  get '/home/inicio', to: 'home#index'

  scope '/login' do
    get '/acesso', to:'login#new'
    post '/acessorecebendo', to:'login#create'
    get '/sair', to:'login#destroy'
  end

  resources :login
  resources :home
  resources :produtos
  resources :fornecedors
end

和错误:

  

没有路由匹配{:action =&gt;“show”,:controller =&gt;“login”},缺少   必填项:[:id]

行:

def require_user
  redirect_to login_path unless current_user   
end

关键是:如果我删除在Login控制器中找到的行“ before_action:... ”,我收到此错误:

  

找不到'id'= 2

的用户

new.html.erb(登录视图):

<% if flash[:notice] %>
  <div class="notice"><%= flash[:notice] %></div> 
<% end %>

<div class="login-page">   
  <div class="form">
    <form class="register-form" action="/login/acessorecebendo" method="post">
      <input type="text" name="login[email]" placeholder="Email"/>
      <input type="password" name="login[senha]" placeholder="Senha"/>
      <button>Cadastrar</button>
      <p class="message">Já é registrado? <a href="#">Login</a></p>
    </form>
    <form class="login-form" action="/login/acessorecebendo" method="post">
      <input type="text" name="login[email]" placeholder="email"/>
      <input type="password" name="login[senha]" placeholder="password"/>
      <button>login</button>
      <p class="message">Não está registrado <a href="#">Criar uma conta</a></p>
    </form>
    <% if session[:user] %>
      <a href="/login/sair">Sair sessão <%= @user.nome %> </a>
    <% end %>
  </div>
</div>

所以,要尝试解决这个问题,我需要做一个方法来检查是否有人登录并重定向到正确的视图。我在尝试之前尝试做这样的事情......

有人可以向我解释一下吗? :\

我尝试遵循此解决方案:Couldn't find User with id=1

但它不起作用..

1 个答案:

答案 0 :(得分:0)

这个问题:

redirect_to login_path unless current_user

login_path是否需要id,您可以通过在控制台中运行rake routes来查看:

           acesso GET    /login/acesso(.:format)          login#new
  acessorecebendo POST   /login/acessorecebendo(.:format) login#create
             sair GET    /login/sair(.:format)            login#destroy
      login_index GET    /login(.:format)                 login#index
                  POST   /login(.:format)                 login#create
        new_login GET    /login/new(.:format)             login#new
       edit_login GET    /login/:id/edit(.:format)        login#edit
            login GET    /login/:id(.:format)             login#show
                  PATCH  /login/:id(.:format)             login#update
                  PUT    /login/:id(.:format)             login#update
                  DELETE /login/:id(.:format)             login#destroy
       home_index GET    /home(.:format)                  home#index
                  POST   /home(.:format)                  home#create
         new_home GET    /home/new(.:format)              home#new
        edit_home GET    /home/:id/edit(.:format)         home#edit
                  GET    /home/:id(.:format)              home#show
                  PATCH  /home/:id(.:format)              home#update
                  PUT    /home/:id(.:format)              home#update
                  DELETE /home/:id(.:format)              home#destroy

(为了简洁起见,我删除了一些。)

我猜你可能想做:

redirect_to accesso_path unless current_user

或者,可能:

redirect_to new_login_path unless current_user

顺便说一句,他们都指向同一个地方,所以你可能会摆脱accesso_path并将其替换为login_new

所以,另一个问题就是你可能会(根据你的评论)听到id中的session[:user_id]无效。当您删除before_action :require_user时,您将进入:

def new
  if session[:user]
    @user = User.find(session[:user])
  end
end

然后提出异常:

  

找不到'id'= 2

的用户

所以,这可能是你应该做的:

class LoginController < ApplicationController
  skip_before_action :verify_authenticity_token
  protect_from_forgery
  before_action :go_home_if_signed_in
  helper_method :current_user
  # ^^^
  # I don't know what this is


  def go_home_if_signed_in
    if session[:user_id]
      # there was a session[:user_id]
      # use find_by instead of find because it won't raise an exception
      if User.find_by(id: session[:user_id])
        # the session[:user_id] resulted in a valid user, so
        # send the user to their home page.
        redirect_to home_index_path
      else
        # if the User wasn't found, then you'll be in here, without
        # raising an exception.
        # So now you want to set the session[:user_id] to nil
        # because it's invalid.
        session[:user_id] = nil
      end
    end
  end

  # you should be able to get rid of this.
  # def require_user
  #   redirect_to new_login_path unless current_user # or wherever, but not login_path
  # end

  def show

  end

  def new
    # This seems wrong. What is session[:user] and how do you 
    # expect User to find it?
    # if session[:user]
    #   @user = User.find(session[:user])
    # end
  end

  def destroy
    # Make sure you set session[:user] = nil somewhere!!!
    reset_session
    # ^^^
    # I don't know what this is.
    # redirect_to "/login/acesso", notice: "Você foi deslogado"
    redirect_to :acesso_path, notice: "Você foi deslogado"
    # ^^^
    # Why not use the path you generated in routes? You went through
    # the trouble of defining it.
  end

  def create
    user = User.validate(login_params[:email], login_params[:senha])
    if user
      session[:user] = user.id
      redirect_to "/home/inicio", notice: "login feito com sucesso"
    else
      redirect_to "/login/acesso", notice: "Dados incorretos"
    end
  end

  private

  def login_params
    params.require(:login).permit(:email, :senha)
  end
end