ActiveRecord错误:找不到没有ID的用户

时间:2013-02-13 04:46:00

标签: ruby-on-rails omniauth rails-activerecord

我一直在构建一个网络应用,允许用户使用Facebook登录,然后重定向到他们的个人资料Feed。如果用户不存在,将使用其Facebook凭据创建新记录并将其存储在“用户”模型中。

我遇到的问题是,当我尝试从Facebook回调重定向回到用户的个人资料页面时,无法找到他们的记录(我在UsersController中显示错误 ActiveRecord :: RecordNotFound#show ),无论记录是否已存在或已在登录过程中新创建。

我使用OmniAuth进行身份验证和访问Facebook Graph API,松散地遵循Ryan Bates RailsCast#360(http://railscasts.com/episodes/360-facebook-authentication?autoplay=true)中列出的约定

这是我的用户模型:

class User < ActiveRecord::Base
  def self.from_omniauth(auth)  
    where(auth.slice(:uid)).first_or_create.tap do |user|
       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.img_url = auth.info.image
       user.save!
    end
  end
end

以及两个相关的控制器,

SessionsController:

class SessionsController < ApplicationController
  def new
    redirect_to '/auth/facebook'
  end

  def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to user
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url
  end
end

和UsersController:

class UsersController < ApplicationController
  def show
    @user = User.find(params[:uid])
  end
end

跟踪数据和会话转储

此外,跟踪显示错误发生在Users控制器的'show'方法中:

app/controllers/users_controller.rb:4:in `show'

我不明白为什么显示用户的查询使用不属于模型的id字段,如请求参数中所示:

{"id"=>"1"}

和会话转储:

_csrf_token: "sjym9SfVWrLipH/7Lxn4RCp2Df6kQTNITnhjro2tirI="
session_id: "7d2c6e70bcae6f1ec257fd634a73c44b"
user_id: 1

最令人困惑的是,当我使用rails控制台检查Users数据库时,将返回以下散列,其中包含一个不属于原始模式的附加ID字段:

=> #<User id: 1, uid: "1123581321", name: "Bob Loblaw", oauth_token: "AAAHFZAqhAyeEBADdZCxeCIdFQWjkbQFjfGfJjCiZA8VKSAw5zy...", oauth_expires_at: "2013-04-14 01:15:20", created_at: "2013-02-13 01:19:24", updated_at: "2013-02-13 01:57:18", img_url: "http://graph.facebook.com/1123581321/picture?type=s..."> 

架构:

create_table "users", :force => true do |t|
  t.string   "uid"
  t.string   "name"
  t.string   "oauth_token"
  t.datetime "oauth_expires_at"
  t.datetime "created_at",       :null => false
  t.datetime "updated_at",       :null => false
  t.string   "img_url"
end

路线

路线是相当标准的,我不相信那里存在问题:

resources :users

root to: 'static_pages#home'

match 'auth/:provider/callback', to: 'sessions#create'
match 'auth/failure', to: redirect('/')
match 'signout', to: 'sessions#destroy', as: 'signout'

match '/how_it_works',    to: 'static_pages#how_it_works'
match '/about',   to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'

1 个答案:

答案 0 :(得分:2)

因为rails正在查找保存在数据库中的user_id以访问记录。所以你需要把它作为

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

当您展示特定用户时。 rails需要找到user_id。这就是你得到这个错误的原因。

如果您查看会话创建方法,则通过会话创建[:id] = user.id

创建表时会自动创建user_id列。