私は Ruby on Rails にまったく慣れていないので、ご容赦ください。
ユーザーが Facebook からサインインできるようにしたい。railscast #265 Devise and OmniAuth (revised) に従いました。Railscast では、ユーザーは Facebook にログインする前に電子メールアドレスを求められます。事前にメールアドレスを必要とせずにFacebookからサインインできるようにしたい.
私が使っているもの: The Devise と Omniauth-facebook gems
私の期待: ユーザーがリンクをクリックし、Facebook からログインすると、Facebook がメール、名前、uid を返し、アプリがそれをデータベースに保存し、ユーザーが作成されます。
私が得るもの:エラーメッセージActiveRecord::StatementInvalid in OmniauthCallbacksController#facebook
SQLite3::ConstraintException: constraint failed: INSERT INTO "users" ("created_at", "current_sign_in_at", "current_sign_in_ip", "email", "encrypted_password", "last_sign_in_at", "last_sign_in_ip", "name", "provider", "remember_created_at", "reset_password_sent_at", "reset_password_token", "sign_in_count", "uid", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
これは私の user.rb モデルです:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
# Nodig als :validatable uit is
#validates_presence_of :email, :if => :email_required?
#validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed?
#validates_format_of :email, :with => Devise.email_regexp, :allow_blank => true, :if => :email_changed?
#
#validates_presence_of :password, :if => :password_required?
#validates_confirmation_of :password, :if => :password_required?
#validates_length_of :password, :within => Devise.password_length, :allow_blank => true
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.email
user.name = auth.info.name
end
end
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"], without_protection: true) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def email_required?
provider == :facebook
end
def password_required?
super && provider.blank?
end
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end
end
これは、ユーザーに OmniAuth を追加するための私の移行です (ユーザーは既にメールを持っています)
class AddOmniauthToUsers < ActiveRecord::Migration
def change
add_column :users, :provider, :string
add_column :users, :uid, :string
add_column :users, :name, :string
end
end
そして、これは私の OmniAuth Callback コントローラーです:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash.notice = "Loged in!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :all
end
前もって感謝します
編集:スタックトレース:
app/models/user.rb:23:in `from_omniauth'
app/controllers/omniauth_callbacks_controller.rb:3:in `all'
編集:サーバーログ奇妙なことです。印刷するauth
と、サーバーログに名前、電子メール、プロバイダー、および uid が表示されます。ただし、次のように表示されます。
INSERT INTO "users" ("created_at", "current_sign_in_at", "current_sign_in_ip", "email", "encrypted_password", "last_sign_in_at", "last_sign_in_ip", "name", "provider", "remember_created_at", "reset_password_sent_at", "reset_password_token", "sign_in_count", "uid", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 26 Feb 2013 17:20:23 UTC +00:00], ["current_sign_in_at", nil], ["current_sign_in_ip", nil], ["email", nil], ["encrypted_password", ""], ["last_sign_in_at", nil], ["last_sign_in_ip", nil], ["name", nil], ["provider", "facebook"], ["remember_created_at", nil], ["reset_password_sent_at", nil], ["reset_password_token", nil], ["sign_in_count", 0], ["uid", "XXXXX"], ["updated_at", Tue, 26 Feb 2013 17:20:23 UTC +00:00]]
SQLite3::ConstraintException: constraint failed: INSERT INTO "users" ("created_at", "current_sign_in_at", "current_sign_in_ip", "email", "encrypted_password", "last_sign_in_at", "last_sign_in_ip", "name", "provider", "remember_created_at", "reset_password_sent_at", "reset_password_token", "sign_in_count", "uid", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
たとえば、名前、電子メールですnil
が、プロバイダーと uid (現在は XXXXX) が入力されています。ユーザー モデルに名前と電子メールを追加しました。多分ここに問題がありますか?これは役に立ちますか?