【问题标题】:trying to get omniauth-facebook to work undefined method `user_id' for nil:NilClass rails试图让omniauth-facebook为nil工作未定义的方法`user_id':NilClass rails
【发布时间】:2014-05-05 23:45:20
【问题描述】:

我正在使用 ryan bates facebook 身份验证 railscast 和 coderwall 上的这篇文章来实现带有omniauth-facebook 的登录功能

https://coderwall.com/p/bsfitw

所以对于我的 gemfile,我有这两个

gem 'omniauth'
gem 'omniauth-facebook'

这是我的omniauth.rb

OmniAuth.config.logger = Rails.logger

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, 'commentedoutappid', 'commentedoutsecretid'
end

我的路线是这样的

  match 'auth/:provider/callback', to: 'sessions#create', via: [:get, :post]
  match 'auth/failure', to: redirect('/'), via: [:get, :post]
  match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post]

  resources :movies do 
    resources :reviews
  end 
  root to: 'movies#index'

这是我的会话控制器

class SessionsController < ApplicationController
  def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = current_user.user_id 
    redirect_to root_url
  end
end 

这是我的用户模型

class User < ActiveRecord::Base
  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
      user.provider = auth.provider 
      user.uid = auth.uid
      user.name = auth.info.name
      user.oauth_token = auth.credentials.oauth_token 
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save
     end
   end 
end

这是我的用户表

  create_table "users", force: true do |t|
    t.string   "provider"
    t.string   "uid"
    t.string   "name"
    t.string   "oauth_token"
    t.datetime "oauth_expires_at"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
  end

我的 application.html.erb 中有这些链接

<div id="user-widget">
  <% if current_user %>
    Signed in as <strong><%= current_user.name %></strong>!
    <%= link_to "Sign out", signout_path, id: "sign_out" %>
  <% else %>
    <%= link_to "Sign in with facebook", "/auth/facebook", id: "sign_in" %>
  <% end %>
</div>

当我点击指向 auth/facebook 的链接时

我在我的会话控制器中得到了undefined methoduser_id' for nil:NilClass`。

哦,我还有一个 current_user 辅助方法

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

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

到目前为止,我完全了解流程,但不了解错误。我完全按照指南从上到下。

我从一个空白的 rails 4 应用开始。我什至尝试安装设计,所以给出了一个 current_user,但我最终卸载了设计,因为它们发生冲突。

【问题讨论】:

  • 我的回答解决了您的问题吗?让我知道结果和查询(如果有)。
  • 它可能做到了,但不幸的是我还没有时间。如果它有效,我一定会回来给你一点功劳!

标签: ruby-on-rails facebook omniauth


【解决方案1】:

更新SessionsController 中的create 操作如下:

class SessionsController < ApplicationController
  def create
    user = User.from_omniauth(env["omniauth.auth"]) ## Setting "user" here
    session[:user_id] = user.id  ## Changed this to use the set "user"
    redirect_to root_url
  end
end 

使用user.id 代替current_user.user_id。从逻辑上讲,您将在users 表中拥有id 列,而不是user_id

如你所愿

user = User.from_omniauth(env["omniauth.auth"])

您需要将session[:user_id] = user.id 设置为user 变量具有当前保存的omniauth 用户的实例。

在旁注中,我只是出于好奇检查了您在问题中提供的链接,发现明确提到使用session[:user_id] = user.id。你一定错过了,但我上面的解释会让你知道为什么会这样。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多