2

それで、友人が彼のアプリに Omniauth を追加するのを手伝いましたが、何らかの理由で omniauth は初めてしか機能しませんでした。

しかし今、それは戻ってきています:

     PG::Error: ERROR: duplicate key value violates 
    unique constraint "index_users_on_email" 
DETAIL: Key (email)=() already exists. : INSERT INTO "users" 
("created_at", "provider", "uid", "updated_at", "username") 
VALUES ($1, $2, $3, $4, $5) RETURNING "id"

1つしか受け入れず、「すでに存在する」と言っているようなものです。どうすればこれを機能させることができますか?

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

  has_many :songs
  has_many :comments

  acts_as_voter

  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.username = auth.info.nickname
    end
  end

  def self.new_with_session(params, session)
    if session["devise.user_attributes"]
      new session["devise.user_attributes"] do |user|
          user.attributes = params
        user.valid?
      end
    else
      super
    end
  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

  def email_required?
    super && provider.blank?
  end


end

スキーマ スニピット

 create_table "users", force: true do |t|
    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
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.boolean  "admin"
    t.string   "provider"
    t.string   "uid"
    t.string   "username"
  end

オムニコントローラー

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      flash.notice = "Signed in!"
      sign_in_and_redirect user
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :twitter, :all
end

すべてのアクセス キーは、Railscasts の最新の ep に従って適切にセットアップされます。

4

3 に答える 3

2

より簡単な説明は、一意の電子メールなしでテスト データが生成されたことが原因である可能性があります。/test/fixtures/users.yml を調べてみてください:

one: {
}
two: {
}

次に、それをに変更します

one: {
  email: tester1@stack.com
}
one: {
  email: tester2@stack.com
}

または、ファイルの内容を削除できます。

于 2014-01-14T15:47:01.343 に答える
2

メール フィールドに一意の制約があります。このフィールドは null 不可として定義されており、デフォルト値は "" (空の文字列) であるためです。これは、電子メールを指定しない場合、DBMS がこのフィールドを "" に設定することを意味します。もちろん、一意の制約があるため、空の文字列 email を持つことができるのは 1 人だけなので、電子メールなしで 2 人のユーザーしか追加できません。

制約を手動で作成しなかった場合は、指定しなかったため、最初のフィールドがテーブルの主キーであると想定して、レールが作成したと想定します (メール フィールドにもインデックスがあるようです)。これにより、インデックスと一意の制約の両方が作成されました。

于 2013-08-09T07:40:47.593 に答える