【问题标题】:How to fix Rails NoMethodError: undefined method `User' using BCrypt如何修复 Rails NoMethodError:使用 BCrypt 的未定义方法“用户”
【发布时间】:2020-03-04 09:31:20
【问题描述】:

我正在尝试使用 gem BCript 创建一个登录页面。 在这个错误袭击我之前,一切都很好。我检查了所有项目,但仍然不明白错误来自哪里,我几乎可以肯定这不是来自 UsersController 中的创建方法。但我在其他地方没有看到错误。 错误:

NoMethodError in UsersController#create
undefined method `User' for #<User:0x0000000007c7f720>

使用这些参数:

Parameters:

{"authenticity_token"=>"Up3fTyw3rT6aNWgcg3eIUVsw8tboFmjbtQcdYDxUYobFiBnG3USB4aiIhqOYLkYafWykoYJupOzMxAGkxLLY3A==",
 "user"=>{"name"=>"nome", "email"=>"nome@nome.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"},
 "commit"=>"Cadastrar"}

尝试创建新用户后,在 view/user/new 中。

   <%= form_for @user do |f| %>
    <% if @user.errors.any? %>
        <div id="error_explanation">
            <div class="alert-error">
                O formulário contém <%= pluralize(@user.errors.count, "erro") %>.
            </div>
            <ul>
                <% @user.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>

    <div class="field">
        <%= f.label :name %>
        <%= f.text_field :name %>
    </div>
    <div class="field">
        <%= f.label :email %>
        <%= f.email_field :email %>
    </div>
    <div class="field">
        <%= f.label :password %>
        <%= f.password_field :password %>
    </div>
    <div class="field">
        <%= f.label :password_confirmation %>
        <%= f.password_field :password_confirmation %>
    </div>
    <div class="actions">
        <%= f.submit "Cadastrar"%>
    </div>
<% end %>

这是用户控制器:

   class UsersController < ApplicationController
  def index
    @users = User.all
  end

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to @user, notice: "Usuário foi criado com sucesso!"
      sign_in(@user)
    else 
      render action: :new
    end
  end

  private
    def user_params
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end
end

这里是会话控制器:

    class SessionsController < ApplicationController
  before_action :block_access, except: [:destroy]

  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && user.authenticate(params[:session][:password])
      sign_in @user
    else
      render 'new'
    end
  end

  def destroy
    sign_out
    redirect_to root_url
  end
end

和应用控制器:

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper

结束

和会话助手

module SessionsHelper
def sign_in
    session[:user_id] = @user.id
end

def current_user
    @current_user ||= User.find_by(id: session[:user_id])
end

def block_access
    if current_user.present?
        redirect_to users_path
    end
end

def logged_in?
    !current_user.nil?
end

def sign_out
    session.delete(:user_id)
    @current_user = nil
end

结束

用户助手中没有任何内容

module UsersHelper
end

我正在使用以下路线:

Rails.application.routes.draw do
  get 'sessions/new'
  resources :users
  get    'sign_in'   => 'sessions#new'
  post   'sign_in'   => 'sessions#create'
  delete 'sign_out'  => 'sessions#destroy'
  root 'sessions#new'
end

我的模特:

   class User < ApplicationRecord
        has_secure_password
        validates name, presence: true, length: { maximum: 50 }
        validates password, presence: true, length: { minimum: 6 }
        VALID_EMAIL_FORMAT = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
        validates email, presence: true, length: { maximum: 260 }, format: { with: VALID_EMAIL_FORMAT}, uniqueness: { case_sensitive: false }
        before_save { self.email = email.downcase }
    end

用户等级:

    class User < ApplicationRecord
    has_secure_password
    validates name, presence: true, length: { maximum: 50 }
    validates password, presence: true, length: { minimum: 6 }
    VALID_EMAIL_FORMAT = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
    validates email, presence: true, length: { maximum: 260 }, format: { with: VALID_EMAIL_FORMAT}, uniqueness: { case_sensitive: false }
    before_save { self.email = email.downcase }
end

查看/用户/新:

    <%= form_for @user do |f| %>
    <% if @user.errors.any? %>
        <div id="error_explanation">
            <div class="alert-error">
                O formulário contém <%= pluralize(@user.errors.count, "erro") %>.
            </div>
            <ul>
                <% @user.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>

    <div class="field">
        <%= f.label :name %>
        <%= f.text_field :name %>
    </div>
    <div class="field">
        <%= f.label :email %>
        <%= f.email_field :email %>
    </div>
    <div class="field">
        <%= f.label :password %>
        <%= f.password_field :password %>
    </div>
    <div class="field">
        <%= f.label :password_confirmation %>
        <%= f.password_field :password_confirmation %>
    </div>
    <div class="actions">
        <%= f.submit "Cadastrar"%>
    </div>
<% end %>

查看/用户/显示:

<html>
<body>
    <h3>Perfil de <%= @user.name %> </h3>
    <%= @user.email %>
</body>

查看/用户/索引:

    <h1> Users </h1>
 <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      <% @users.each do |user| %>
        <tr>
          <td><%= user.name %></td>
          <td><%= user.email %></td>
          <td><%= link_to "Show", user %></td>
        </tr>
     <%end%>
   </tbody>
</table>

查看/会话/新建

    <%= form_for :session, url: sign_in_path do |f| %>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password, autocomplete: "off" %>
  </div>
  <div class="actions">
    <%= f.submit "Log in" %>
  </div>
<p>New user? <%= link_to "Sign up now!", new_user_path %></p>
<% end %>

布局/_head

    <header>
  <div>
    <nav>
      <ul>
        <% if logged_in? %>
          <li><%= link_to "Users", users_path %></li>
          <li>
            <ul>
              <li><%= link_to "Profile", current_user %></li>
              <li><%= link_to "Settings", '#' %></li>
              <li>
                <%= link_to "Log out", sign_out_path, method: "delete" %>
              </li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to "Log in", root_path %></li>
        <% end %>
      </ul>
    </nav>
  </div>
</header>

整页错误:

有人知道如何解决这个问题吗? 整页错误:https://imgur.com/a/EEnV0fm

【问题讨论】:

  • 你能提供你的错误调用堆栈吗?另外,您是否尝试切换redirect_to 和sign_in 的位置?我想您需要先登录用户然后重定向。
  • NoMethodError in UsersController#create undefined method `User' for #<0x000000000b544dd0>

标签: ruby-on-rails


【解决方案1】:

难道不是因为即使在重定向之后您仍试图调用 sign_in() 方法吗?
在语句末尾调用 redirect_to:

def create
  @user = User.new(user_params)
  if @user.save
    sign_in(@user)
    redirect_to @user, notice: "Usuário foi criado com sucesso!"
  else 
  ...

【讨论】:

  • 这是有道理的,但似乎还不是原因。我已经更改了顺序,但仍然出现同样的错误。
【解决方案2】:

你需要将用户传递给sign_in方法:

def sign_in user
  session[:user_id] = user.id
end

在你的控制器上你是这样称呼它的:

sign_in @user

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2018-06-16
    • 2015-06-30
    相关资源
    最近更新 更多