Rails控制器返回未定义的方法'save',但无论如何都要保存

时间:2017-07-18 15:15:04

标签: ruby-on-rails omniauth

我一直在努力让Omniauth与多家供应商合作,现在已经工作了几天。我终于有了(大部分)工作 - Facebook和Twitter正如预期的那样同步,但是我遇到了Steam的问题。

class AuthenticationsController < ApplicationController
  skip_before_action :verify_authenticity_token, :only => :steam

  def index
    @authentications = current_user.authentications.all
  end
  # <%= link_to 'Authentications', authentications_path %>
  def home
  end

  def twitter
     omni = request.env["omniauth.auth"]
     authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])

     if authentication
      flash[:notice] = "Logged in Successfully"
      sign_in_and_redirect User.find(authentication.user_id)
     elsif current_user
      token = omni['credentials'].token
      token_secret = omni['credentials'].secret

      current_user.authentications.create!(:provider => omni['provider'], 
                                          :uid => omni['uid'], 
                                          :token => token, 
                                          :token_secret => token_secret)
      flash[:notice] = "Authentication successful."
      sign_in_and_redirect current_user
     else
      user = User.new
      user.apply_omniauth(omni)
      raise user.inspect
      if user.save
         flash[:notice] = "Logged in."
         sign_in_and_redirect User.find(user.id)             
      else
         session[:omniauth] = omni.except('extra')
         redirect_to new_user_registration_path
      end
     end 
   end

   def destroy
     @authentication = Authentication.find(params[:id])
     @authentication.destroy
     redirect_to authentications_url, :notice => "Successfully destroyed authentication."
   end


   def facebook
     omni = request.env["omniauth.auth"]
     authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])

     if authentication
      flash[:notice] = "Logged in Successfully"
      sign_in_and_redirect User.find(authentication.user_id)
     elsif current_user
      token = omni['credentials'].token
      token_secret = ""

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

      flash[:notice] = "Authentication successful."
      sign_in_and_redirect current_user
     else
      user = User.new
      user.email = omni['extra']['raw_info'].email 

      user.apply_omniauth(omni)

      if user.save
         flash[:notice] = "Logged in."
         sign_in_and_redirect User.find(user.id)             
      else
         session[:omniauth] = omni.except('extra')
         redirect_to new_user_registration_path
      end
     end
   end

    def steam
        omni = request.env["omniauth.auth"]
        authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])

        if authentication
            flash[:notice] = "Logged in Successfully"
            sign_in_and_redirect User.find(authentication.user_id)
        elsif current_user
        token = omni['extra']['raw_info'].steamid
        # render :text => request.env["omniauth.auth"].info.to_hash.inspect

        puts token
        token_secret = ""

            current_user.authentications.create!(:provider => omni['provider'], 
                                                 :uid => omni['uid'], 
                                                 :token => token, 
                                                 :token_secret => token_secret)
            flash[:notice] = "Authentication successful."
            sign_in_and_redirect current_user
        else
            user = User.new
            user.apply_omniauth(omni)
        end

        if user.save
            flash[:notice] = "Logged in."
            sign_in_and_redirect User.find(user.id)             
        else
            session[:omniauth] = omni.except('extra')
            redirect_to new_user_registration_path
        end
    end




end

正如您所看到的,twitter函数和steam几乎是重复的 - 它们引用User model中的函数

def apply_omniauth(omni)
    authentications.build(:provider => omni['provider'], 
                          :uid => omni['uid'],
                          :token => omni['credentials'].token, 
                          :token_secret => omni['credentials'].secret)
  end

目前Steam会回复undefined method 'save' for nil

if user.save
    flash[:notice] = "Logged in."
    sign_in_and_redirect User.find(user.id)             
else

让我感到困惑的是它实际上正在拯救。

 => #<Authentication id: 12, provider: "steam", uid: "redacted", token: "76561198038103683", token_secret: "", created_at: "2017-07-18 14:57:32", updated_at: "2017-07-18 14:57:32", user_id: 2> 
2.4.1 :022 > u.authentications.last.destroy
  Authentication Load (0.8ms)  SELECT  "authentications".* FROM "authentications" WHERE "authentications"."user_id" = $1 ORDER BY "authentications"."id" DESC LIMIT $2  [["user_id", 2], ["LIMIT", 1]]
   (0.3ms)  BEGIN
  SQL (0.6ms)  DELETE FROM "authentications" WHERE "authentications"."id" = $1  [["id", 13]]
   (4.2ms)  COMMIT
 => #<Authentication id: 13, provider: "steam", uid: "redacted", token: "redacted", token_secret: "", created_at: "2017-07-18 15:13:00", updated_at: "2017-07-18 15:13:00", user_id: 2> 
2.4.1 :023 > u.authentications.last
  Authentication Load (0.6ms)  SELECT  "authentications".* FROM "authentications" WHERE "authentications"."user_id" = $1 ORDER BY "authentications"."id" DESC LIMIT $2  [["user_id", 2], ["LIMIT", 1]]
 => #<Authentication id: 14, provider: "steam", uid: "redacted", token: "redacted", token_secret: "", created_at: "2017-07-18 15:13:19", updated_at: "2017-07-18 15:13:19", user_id: 2> 

我删除了记录 - 然后去重新验证,并得到相同的错误,但关系确实存在。

我不确定如何打印user以查看它发生了什么,或者如何在其中进行错误测试。

任何反馈都是受欢迎的,这个宝石花了很长时间。

1 个答案:

答案 0 :(得分:0)

因此,您只在user分支中设置else变量。如果评估任何其他分支user变量为零。如果以下情况,只需将{if user.save)移至else的第二个分支:

  def steam
    omni = request.env["omniauth.auth"]
    authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])

    if authentication
        flash[:notice] = "Logged in Successfully"
        sign_in_and_redirect User.find(authentication.user_id)
    elsif current_user
    token = omni['extra']['raw_info'].steamid
    # render :text => request.env["omniauth.auth"].info.to_hash.inspect

    puts token
    token_secret = ""

        current_user.authentications.create!(:provider => omni['provider'], 
                                             :uid => omni['uid'], 
                                             :token => token, 
                                             :token_secret => token_secret)
        flash[:notice] = "Authentication successful."
        sign_in_and_redirect current_user
    else
        user = User.new
        user.apply_omniauth(omni)
        if user.save
          flash[:notice] = "Logged in."
          sign_in_and_redirect User.find(user.id)             
        else
          session[:omniauth] = omni.except('extra')
          redirect_to new_user_registration_path
        end
    end
end