Как исправить Rails NoMethodError: неопределенный метод `User 'с использованием BCrypt - PullRequest
1 голос
/ 03 марта 2020

Я пытаюсь создать страницу входа, используя гем BCript. Все было хорошо, пока эта ошибка не поразила меня. Я проверил весь проект и до сих пор не понимаю, откуда возникла ошибка, я почти уверен, что это не из метода create в 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"}

После попытки создать нового пользователя в представлении / пользователь / новый.

   <%= 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

end

и сессии helper

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

end

ничего в пользователях helper

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

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Вам нужно передать пользователя методу sign_in:

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

На вашем контроллере вы вызываете его так:

sign_in @user
0 голосов
/ 03 марта 2020

не правда ли, потому что вы пытаетесь вызвать метод 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 
  ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...