Rails NoMethodError undefined method `provider' for nil:NilClass

纵然是瞬间 提交于 2020-04-30 08:47:22

问题


I'm so close to getting google auth to work for my rails app, I have the client id and secret key all set up under initializers but I don't know what else I'm missing?

I installed the google-auth2 gem and migrated my table. When I press "Sign in" without filling anything out on the sign in page, (it should just tell me to fill in with an Email and Password) I get this error, and when I sign in with a user I also get this error...

Error:

NoMethodError in SessionsController#create
undefined method `provider' for nil:NilClass
Extracted source (around line #9):
7
8
9
10
11
12


    def self.from_omniauth(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user|
          user.provider = auth.provider
          user.uid = auth.uid
          user.name = auth.info.name

Sessions controller:

class SessionsController < ApplicationController
    def new
        @user = User.new
    end
    def create
        unless params[:email].empty?
            @user = User.find_by_email(params[:email])
            if @user && @user.authenticate(params[:password])
                session[:user_id] = @user.id
                redirect_to albums_path
            else
                flash[:alert] = "Email or Password Incorrect.  Please try again."
                redirect_to signin_path
            end
        else
                flash[:alert] = "Please include your Email & Password."
                redirect_to signin_path
        end
            if
                @user = User.from_omniauth(request.env["omniauth.auth"])
                    session[:user_id] = @user.id
                    redirect_to root_path
            end
    end
    def destroy
        session.clear
        redirect_to root_path
    end

end

User model:

class User < ApplicationRecord
    has_secure_password
    validates :email, uniqueness: true, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
    validates :name, uniqueness: true, length: {in: 3..20}, presence: true
    has_many :reviews
    has_many :albums, through: :reviews

    def self.from_omniauth(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user|
          user.provider = auth.provider
          user.uid = auth.uid
          user.name = auth.info.name
          user.oauth_token = auth.credentials.token
          user.oauth_expires_at = Time.at(auth.credentials.expires_at)
          user.save!
        end
      end
end

Sessions login form:

<% unless flash[:alert].nil? %>
  <p><strong><%= flash[:alert] %></strong></p>
<% end %>
<%= form_tag '/signin' do %>
<% if @user.errors.any? %>
<ul>
  <% @user.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
</ul>
<% end %>
    <%= label_tag :email %>
    <%= text_field_tag :email %>
    <%= label_tag :password %>
    <%= password_field_tag :password %>
    <%= submit_tag "Sign in" %>
<br><br>
     <a href="/auth/google_oauth2">Sign in with Google</a>
<% end %>

initializers.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
    provider :google_oauth2, "client-id-changed-for-stackoverflow", "secret-key"
  end

routes.rb

Rails.application.routes.draw do
  get 'auth/:provider/callback', to: 'sessions#create'
  get 'auth/failure', to: redirect('/')
  get '/signup' => 'users#new', as: 'signup'
  post '/signup' => 'users#create'
  get '/signin' => 'sessions#new'
  post '/signin' => 'sessions#create'
  get '/signout' => 'sessions#destroy'
  post '/logout', to: "sessions#destroy"

  resources :albums do
    resources :reviews, except: [:index]
  end
  resources :users, only: [:show, :destroy]
  resources :reviews, only: [:index]

  root to: "albums#index"
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

Add Columns migration:

class AddColumnsToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :provider, :string
    add_column :users, :uid, :string
 end
end

LOG

Started POST "/signin" for ::1 at 2020-04-18 20:42:13 -0400
Processing by SessionsController#create as HTML
  Parameters: {"authenticity_token"=>"33vGGzcGDDuqWWRzZfAH/mhjdK66w3XJhzGNSn3P4Xd021XRdTU9tw5XQgR", "email"=>"", "password"=>"[FILTERED]", "commit"=>"Sign in"}
Redirected to http://localhost:3000/signin
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.0ms | Allocations: 1096)

NoMethodError (undefined method `provider' for nil:NilClass):

app/models/user.rb:9:in `from_omniauth'
app/controllers/sessions_controller.rb:20:in `create'

来源:https://stackoverflow.com/questions/61296725/rails-nomethoderror-undefined-method-provider-for-nilnilclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!