我正在尝试从最近2天找出这个问题,但直到现在都无济于事。我正在使用rails中的omniauth,我已经在我的网站中集成了omniauth身份验证,但我想为所有提供者创建单独的表。我有两个表1:用户和其他是auth_provider 1:用户将包含用户数据 2:auth_provder将包含带有社交媒体提供商身份验证详细信息的user_id。
我已经创建了从用户到auth_providers的has_many关联。
现在我想在两个表中插入数据,以便首先在用户表中创建包含一些字段的条目,然后它应该采用新插入的记录条目并将此id与其他数据一起插入到auth_providers表中。我知道这件事是可能的,但我找不到任何示例或代码。我只是在过去2天搜索和尝试,但仍然没有成功。我想使用关联来做它,我也使用了nested_attributes,但仍然没有成功。
这是我的代码
用户模型:
class User < ApplicationRecord
# Include default devise modules. Others available are:
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable,
:omniauthable, :omniauth_providers => [:facebook,:twitter,:linkedin]
has_many :organizations_users
has_many :auth_providers
has_many :organizations, through: :organizations_users
accepts_nested_attributes_for :auth_providers
def active_for_authentication?
# Uncomment the below debug statement to view the properties of the returned self model values.
super && self.active && self.exp_alert == false
end
def self.from_omniauth(auth)
exist = where(email: auth.info.email).first
if exist
existing_user = exist["id"]
Auth_provider.where(provider: auth.provider, social_uid: auth.uid).first_or_create do |auth_provider|
auth_provider.provider = auth.provider
auth_provider.social_uid = auth.uid
auth_provider.social_token = auth.credentials.token
auth_provider.user_id = existing_user
end
else
#@organization.users.create(first_name:params[:first_name])
names = auth.info.name.strip.split(" ")
first_name = names[0]
last_name = names[1]
params = { user: {
email: 'abc@abc.com', auth_providers_attributes: [
{ provider: 'facebook' },
{ social_token: 'asfasf2342432' },
{ social_uid: 'asfdaf23242'} # this will be ignored
]
}}
user = User.create(params[:user])
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
def self.find_or_create_from_auth_hash(auth_hash)
user = where(provider: auth_hash.provider, uid: auth_hash.uid).first_or_create do |user|
user.first_name = auth_hash.info.nickname
user.active = 'true'
user.admin=='false'
user.exp_alert = 'false'
user.password = Devise.friendly_token[0,20]
user.token = auth_hash.credentials.token
user.email = auth_hash.info.email
user.secret = auth_hash.credentials.secret
user.skip_confirmation!
end
user
end
def self.linkedin_hash(auth_hash)
user = where(provider: auth_hash.provider, uid: auth_hash.uid).first_or_create do |user|
user.first_name = auth_hash.info.first_name
user.last_name = auth_hash.info.last_name
user.active = 'true'
user.admin = 'false'
user.exp_alert = 'false'
user.password = Devise.friendly_token[0,20]
user.token = auth_hash.credentials.token
user.email = auth_hash.info.email
user.skip_confirmation!
end
user
end
def inactive_message
"Your Account has not been active yet."
end
def after_confirmation
super
self.update_attribute(:active, true)
end
end
auth_providers模型
class Auth_provider < ApplicationRecord
devise :database_authenticatable
belongs_to :user
accepts_nested_attributes_for :user
end
来自facebook的回复是
#<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash expires=true expires_at=1517924507 token="EAAdDsC4F0CCLq95eo81qfaMVVs0zeNgqtRqUF9ufZB3gK609NY3aiikJ9AvE8zSB63WFcG0E6NBFNIWf00DjgHNlsQHCd2D26uxJ1ongQ5YBJZCeuZAOas2SEYlRwPYhctfiEVVdbadOyA3QeL50JHIA5dKa3xdfK5Efw9Y"> extra=#<OmniAuth::AuthHash raw_info=#<OmniAuth::AuthHash email="testing@gmail.com" id="35232364989259" name="John">> info=#<OmniAuth::AuthHash::InfoHash email="testing@gmail.com" image="http://graph.facebook.com/v2.6/35489/picture" name="John"> provider="facebook" uid="354814524989259">
答案 0 :(得分:1)
如果我理解你,你能做点什么:
...
user = User.create(the_user_attributes)
user.auth_providers.create(the_auth_provider_attributes)
...
这应该有效,创建一个用户,然后是属于他们的身份验证提供者。
如果您需要在保存之前稍微操作一下,也可以使用User.new
和user.auth_providers.build
,并且当您在用户上调用save
时,它们将被保留。
<强>更新强>
要将代码拆分为可读块,我建议如下:
<强> user.rb 强>
# update: you're in the user model, so no need to specify the model again in the line below
user = create(user_attributes_from_auth(auth))
user.auth_providers.create(provider_attributes_from_auth(auth))
private
def user_attributes_from_auth(auth)
{ first_name: auth.info.nickname,
token: auth_hash.credentials.token,
etc: etc }
end
def provider_attributes_from_auth(auth)
{ a_similar_approach_as: user_attributes_from_auth }
end
因此,简而言之,您使用^^中的前两行从属性哈希创建用户,然后为auth提供程序执行相同操作。
这很好看且可读,而且实际上并不是你现在所做的。快来看看你的成功 - 希望它有所帮助!