0

我正在尝试将omniauth-identity 集成到我的应用程序中。根据 README 文件,我们只需要编写:

class Identity < OmniAuth::Identity::Models::ActiveRecord
  # Add whatever you like! 
end

但是我想添加唯一性验证。所以简单的方法是将此验证添加到 Identity 类:

validates_uniqueness_of :email, :case_sensitive => false

但是当我浏览 gem 源代码时,我auth_key=在下面看到了这个方法OmniAuth::Identity::Models::ActiveRecord

    def self.auth_key=(key)
      super
      validates_uniqueness_of key, :case_sensitive => false
    end

而且因为我讨厌重复的代码,我想使用现有的方法而不是多写一​​行。所以我将 Identity 类更改为

class Identity < OmniAuth::Identity::Models::ActiveRecord
  # Add whatever you like! 
  auth_key :email
end

但我仍然遇到重复的电子邮件(看起来验证不起作用)。因此我尝试了以下方法Identity.auth_key = 'my_key',它给了我错误NoMethodError: super: no superclass methodauth_key=' for #`

知道我在这里做错了什么吗?当然,我可以在 OmniAuth::Identity::Models::ActiveRecord 中将 auth_key= 方法定义更改为 auth_key,但我讨厌这样做,因为我认为我在这里遗漏了一些东西。

谢谢

4

1 回答 1

3

您快到了...您提供Identity类并继承自OmniAuth::Identity::Models::ActiveRecord,并指定 OmniAuth Identity 应该用来定位记录的列,只需使用auth_keysetter 方法。任何验证都应包含在您的Identity类中,就像它们通常与任何其他ActiveRecord模型一样。

auth_key只是您选择在身份验证时定位记录的列的 getter/setter(虚拟属性),它本身不是列,除非您选择在身份模型中创建auth_key列。

另请注意,OmniAuth Identity 寻求的默认方法是#email属性(https://github.com/intridea/omniauth-identity/blob/master/lib/omniauth/identity/model.rb#L41),因此auth_key如果您选择坚持使用该#email属性。

# app/models/identity.rb
class Identity < OmniAuth::Identity::Models::ActiveRecord
  belongs_to :user
  attr_accessible :email, :password, :password_confirmation, :user_id

  validates :email, :presence => true, :uniqueness => true, :case_sensitive => false
  validates :password, :presence => true, :confirmation => true
  validates :password_confirmation, :presence => true
end

# db/migrate/xxxxxxxxxxxxxx_create_identities.rb
class CreateIdentities < ActiveRecord::Migration
  def change
    create_table :identities, :force => true do |t|
      t.column :email, :string, :null => false
      t.column :password_digest, :string
      t.column :user_id, :integer, :null => false
    end

    change_table :identities do |t|
      t.index :email, { :unique => true }
      t.index :user_id
    end
  end
end

# config/initializers/omniauth.rb
use OmniAuth::Builder do
  provider :identity, :fields => [:email]
end

如果您决定将 auth_key 列更改为其他内容,例如#username,您将使用auth_keysetter,如下所示:

# app/models/identity.rb
class Identity < OmniAuth::Identity::Models::ActiveRecord
  auth_key 'username'
  belongs_to :user
  attr_accessible :password, :password_confirmation, :username, :user_id

  validates :password, :presence => true, :confirmation => true
  validates :password_confirmation, :presence => true
  validates :username, :presence => true, :uniqueness => true
end

# db/migrate/xxxxxxxxxxxxxx_create_identities.rb
class CreateIdentities < ActiveRecord::Migration
  def change
    create_table :identities, :force => true do |t|
      t.column :password_digest, :string
      t.column :username, :string, :null => false
      t.column :user_id, :integer, :null => false
    end

    change_table :identities do |t|
      t.index :username, { :unique => true }
      t.index :user_id
    end
  end
end

# config/initializers/omniauth.rb
use OmniAuth::Builder do
  provider :identity, :fields => [:username]
end

请注意,该auth_key方法接受字符串参数,而不是像attr_accessible.

OmniAuth Identity 非常灵活,您可以利用其他几个自定义项来适应现有项目。您可以为您的身份模型设置自定义类,并且可以自定义在身份验证时找到匹配记录的方式。请参阅https://github.com/intridea/omniauth-identity/blob/master/README.markdown

我希望这一切都会有所帮助,我知道这让我困惑了一段时间,我不得不深入研究并理解 OmniAuth Identity 源代码。

于 2012-08-31T19:57:13.917 回答