Question

I am using Devise + Omniauth to enable Facebook signup in my application. When I was developing it, I encountered no problems. Same with deploying it to my remote server. The problem is, other people keep encountering the same error:

TypeError (no implicit conversion of Symbol into Integer):
app/models/user.rb:67:in `find_for_facebook_oauth'
app/controllers/users/omniauth_callbacks_controller.rb:4:in `facebook'

I have the following code for the User model user.rb:

def self.find_for_facebook_oauth( data, signed_in_resource=nil)
user = User.where(:email => data.info.email).first
unless user
  params =
    {  
      :user =>
      {
        :username => data.uid,
        :email => data.info.email,
        :password => Devise.friendly_token[0,20],
        :user_profile_attributes => 
          {
            :first_name => data.extra.raw_info.first_name,
            :last_name => data.extra.raw_info.last_name,
            :remote_image_url => data.extra.raw_info.image,
          },
        :user_auths_attributes =>
        {
          :uid => data.uid,
          :provider => data.provider
        }
      }
    }
    user = User.create!(params[:user])
end
return user
end

Where line 67 is the user = User.create!(params[:user])

And omniauth_callbacks_controller.rb:

def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
@user = User.find_for_facebook_oauth(request.env["omniauth.auth"])

if @user.persisted?
  sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
  set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
  session["devise.facebook_data"] = request.env["omniauth.auth"]
  redirect_to new_user_registration_url
end
end

Where line 4 is @user = User.find_for_facebook_oauth(request.env["omniauth.auth"])

The server logs also show the GET parameters:

Parameters: {"code"=>"[some long string of number and letters]", "state"=>"[another string of numbers and letters]"}

Update: The logger outputs the following for request.env["omniauth.auth"]:

#<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash expires=true expires_at=1401992074 token="*"> extra=#<OmniAuth::AuthHash raw_info=#<OmniAuth::AuthHash email="*" first_name="*" gender="male" id="*" last_name="*" link="https://www.facebook.com/*" locale="en_US" name="*" timezone=8 updated_time="2014-04-05T09:29:22+0000" username="*" verified=true>> info=#<OmniAuth::AuthHash::InfoHash email="*" first_name="*" image="http://graph.facebook.com/*/picture?type=square" last_name="*" name="*" nickname="*" urls=#<OmniAuth::AuthHash Facebook="https://www.facebook.com/*"> verified=true> provider="facebook" uid="*">

Update 2: Logging the params[:user] provides the following values:

Params: {:username=>"*", :email=>"*", :password=>"iePVLt7XEWk4YwPjja6n", :user_profile_attributes=>{:first_name=>"*", :last_name=>"*", :remote_image_url=>"http://graph.facebook.com/*/picture?type=square"}, :user_auths_attributes=>{:uid=>"*", :provider=>"facebook"}}
Was it helpful?

Solution

Update your params hash as below:

params =
    {  
      :user =>
      {
        :username => data.uid,
        :email => data.info.email,
        :password => Devise.friendly_token[0,20],
        :user_profile_attributes => 
          {
            :first_name => data.extra.raw_info.first_name,
            :last_name => data.extra.raw_info.last_name,
            :remote_image_url => data.info.image ## Removed comma and updated the method
          },
        :user_auths_attributes =>
        [{
          :uid => data.uid,
          :provider => data.provider
        }] ## Enclosed within array [] brackets
      }
    }

Looking at the params hash given by you, I can tell that a User and Profile have a 1-1 Relationship whereas User and Auths has a 1-M Relationship. In that case, user_auths_attributes must be passed as an Array.

TypeError (no implicit conversion of Symbol into Integer)

You were getting the above error because user_auths_attributes was being interpreted as an array and not a hash. So when Ruby saw params[:user][:user_auths_attributes][:uid] it was trying to take the last key and turn it into params[:user][:user_auths_attributes][0] or at least find some integer value it could be converted to index the Array.

OTHER TIPS

I found only this issue:

:remote_image_url => data.extra.raw_info.image # In data I see only data.info.image

replace with

:remote_image_url => data.info.image

But it is not a solution for your question.

Try to debug data from params[:user]. From exception it looks like that you use some Hash on property which is Integer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top