如果用户已使用“本地”电子邮件注册在我的网站上注册,然后注销,则希望使用其Facebook登录,我希望这很好,并“组合”信息整合到一个用户中。这是我这样做的方法:
def self.from_omniauth(auth)
if user = User.find_by(email: auth.info.email)
user.provider ||= auth.provider
user.uid ||= auth.uid
user.first_name ||= auth.info.first_name
user.last_name ||= auth.info.last_name
user.save
user
elsif user = User.create(provider: auth.provider, uid: auth.uid)
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.save
user
end
end
尽管我的测试非常简单,但它似乎工作正常。我只是有几个问题,是一个相对业余的程序员,并且赞赏那些有经验的人的智慧,他们不仅知道“如何”,而且知道“如何最好”。
这是常见的“合法”做法吗?我可能没有想到某些隐私或“最佳做法”问题?
是否有一种方法可以合并find_by
语句的两个分支create
和if/elsif
调用?实际上,this post在使用tap
方面有很好的答案。有什么理由不这样做吗?
与多个提供者进行此操作的通常方法是什么(例如,如果我们正在谈论的用户是谁注册了电子邮件,然后使用Facebook登录,然后使用Google登录)?我最好的猜测是哈希或整个其他ActiveRecord对象。 (您甚至可以将哈希存储为ActiveRecord对象的属性吗?)
我希望可以发布并非完全是问题的问题。感谢您的建议!
答案 0 :(得分:1)
1 )我已经完成了您所做的事情,从主题上看这不是问题。随着用户群的增长,让两个用户使用同一封电子邮件可能会很麻烦。
2 ),您可以使用find_or_create_by
,即:
def self.from_omniauth(auth)
user = User.find_or_create_by(email: auth.info.email) do |u|
u.provider = auth.provider
u.uid = auth.uid
...
end
end
请参见docs
3 )ActiveRecord支持将hash
存储在列中。 https://api.rubyonrails.org/classes/ActiveRecord/Store.html详细说明了如何实现。