在rails中使用OR查询为多个用户设计omniauth

时间:2014-08-07 18:38:16

标签: mysql ruby-on-rails devise omniauth

我希望能够使用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查询。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

首先,auth.slice(:provider, :uid)指的是来自omniauth的auth哈希中的键,但provider2uid2只是数据库中的列,因此它们不能在切片中使用以任何方式,因为他们不是auth哈希中的键(虽然我意识到这只是你的例证/例子)。您需要提取哈希条目,并分别与provideruid列以及provider2uid2列进行比较。另外,要进行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表中与相关用户相关的另一行。您可以与用户联系,或者您希望处理获取关联用户的问题。