Rails - Build不会在数据库中创建记录

时间:2012-11-14 21:42:48

标签: ruby-on-rails authentication devise omniauth

我正在尝试为我当前的设计系统添加身份验证控制器,以便为facebook和twitter提供多个登录。 为此,我正在学习本教程:http://railscasts.com/episodes/236-omniauth-part-2

我的问题是,对于尚未注册的人,并尝试在Twitter注册。 所以我需要为此创建用户和身份验证。

我的代码如下:

      user = User.new
      token = omni['credentials'].token
      token_secret = omni['credentials'].secret
      user.provider = omni.provider
      user.uid = omni.uid

      user.authentications.build(:provider => omni['provider'], :uid => omni['uid'], :token => token, :token_secret => token_secret)

      if user.save
        flash[:notice] = "Logged in."
        sign_in_and_redirect(:user, user)                
      else
        session["devise.user_attributes"] = user.attributes
        redirect_to new_user_registration_path
      end 

因此,在注册过程结束时,将创建新用户。但是在数据库中,我没有看到关于该用户的任何Twitter身份验证记录。

这是因为user.authentications.build?

如果你能帮助我,那将是很棒的。

感谢。

4 个答案:

答案 0 :(得分:3)

作为一个数据点:你所指的轨道广播引用的是Omniauth 1.0之前的版本,它的策略与railscsts引用的策略略有不同。 (注意:我使用的是您在实际网站上引用的确切方法)。在这种情况下,构建调用“apply_omniauth” -

确保您已创建(在视频中引用)一个构建资源的注册控制器。这是我目前的工作示例:

    class RegistrationsController < Devise::RegistrationsController
  def create
    super
    session[:omniauth] = nil unless @user.new_record?
  end

  private

  def build_resource(*args)
    super
    if session[:omniauth]
      # apply omniauth calls the user model and applies omniauth session to the info
      @user.apply_omniauth(session[:omniauth])

      #
      @user.valid?
    end
  end
end

但是,您仍然需要创建身份验证记录,这是我的确切调用:

current_user.authentication.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])

希望它有所帮助。

答案 1 :(得分:2)

是的,这是因为构建

User.build # allocates a new record for you
User.create # allocates and then saves a new record for you

所以我认为你想要

user.authentications.create(:provider => omni['provider'], 
                            :uid => omni['uid'], 
                            :token => token, 
                            :token_secret => token_secret)

此外,您应该处理创建不保存的情况(验证问题)

答案 2 :(得分:0)

我想如果你使用的是Devise + Omniauth,你可以看看这个更新的Railscast。在新版本的Devise gem中有OmniAuth的原生支持。

答案 3 :(得分:0)

是的,因为构建,它用于构建记录而不将其保存在数据库中(如new)。

如果您的模型中有User has_many :authentications,则可以将autosave选项设置为true,以便在保存用户时自动保存身份验证:

has_many :authentications, autosave: true