我希望能够使用omniauth签署用户并设计多个帐户。在我的用户模型中,我将twitter用户的uid设置为等于uid,provider = twitter。对于用户的Facebook uid将等于uid2和provider2 = Facebook。
我目前使用此查询在if auth.slice = provider, uid
中为用户签名,或者如果没有则注册用户。
where(auth.slice(:provider, :uid)).first_or_create do |user|
但是现在我想运行类似的东西:
where(auth.slice(:provider, :uid || :provider2, :uid2 )).first_or_create do |user|
I.e where auth.slice = :provider, :uid OR :provider2, :uid2
基本上我需要能够运行OR查询。
非常感谢任何帮助。
答案 0 :(得分:0)
首先,auth.slice(:provider, :uid)
指的是来自omniauth的auth哈希中的键,但provider2
和uid2
只是数据库中的列,因此它们不能在切片中使用以任何方式,因为他们不是auth哈希中的键(虽然我意识到这只是你的例证/例子)。您需要提取哈希条目,并分别与provider
和uid
列以及provider2
和uid2
列进行比较。另外,要进行OR,您可以使用SQL片段的老派方法:
Users.where('(provider = :provider AND uid = :uid) OR (provider2 = :provider AND uid2 = :uid', {provider: auth[:provider], uid: auth[:uid]})
或使用AREL,因为沼泽标准where
无法处理OR。 AREL自述文件非常易读https://github.com/rails/arel - 您可以执行以下操作:
prov = auth[:provider]
uid = auth[:uid]
users = Arel::Table.new(:users)
users.where(users[:provider].eq(prov).and(users[:uid].eq(uid))).or(users[:provider2].eq(prov).and(users[:uid2].eq(uid)))).project(Arel.sql('*'))
然而,我认为这两个问题的长篇大论强调,每个提供商添加一组列的方法会让事情变得有点痛苦,如果,例如,您通过谷歌,雅虎或其他任何方式添加登录,从而产生provider3,uid3和provider4,uid4 ......另一种方法是使用另一个模型/表来存储这些不同的身份,并与用户建立has_many关系。例如:
class User < ActiveRecord::Base
has_many :identities
...
end
class Identity < ActiveRecord::Base
belongs_to :user
...
end
然后你可以使用简单的
查找身份Identity.where(auth.slice(:provider, :uid))
像你现在一样,不必担心添加新的提供者。它们只会导致identies表中与相关用户相关的另一行。您可以与用户联系,或者您希望处理获取关联用户的问题。