Reputation: 3010
I'm trying to add authentications controller for my current devise system, in order to provide multiple logins with facebook and twitter. To do that, I'm following this tutorial: http://railscasts.com/episodes/236-omniauth-part-2
My problem is, for the person, who hasn't registered yet, and trying to register with twitter. So I need to create both user and authentication for that.
My code is the following:
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
So at the end of the registration process, the new user is created. However in the database, I don't see any twitter authentication record with respect to that user.
Is that because of the user.authentications.build ?
That would be great if you can help me.
Thanks.
Upvotes: 0
Views: 260
Reputation: 4930
Yes it is because of build, it is use to build a record without saving it in the database (like new).
If in your model you have a User
has_many :authentications
, you can set the autosave
option to true to automatically save the authentications when you are saving the user :
has_many :authentications, autosave: true
Upvotes: 0
Reputation: 131
As a data point: The railscasts you're referring to references Omniauth pre-1.0, which had a slighly different strategy than what that railscsts reference. (Note: I'm using the exact method you're referencing on a live site ). In this case, the build calls "apply_omniauth" -
Make sure you've created (as they reference in the video), a registrations controller which builds the resource. Here is my current working example:
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
However, you still need to create the authentication record, here is my exact call:
current_user.authentication.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
Hope it helps.
Upvotes: 3
Reputation: 40277
Yes, it is because of build
User.build # allocates a new record for you
User.create # allocates and then saves a new record for you
So I think you want
user.authentications.create(:provider => omni['provider'],
:uid => omni['uid'],
:token => token,
:token_secret => token_secret)
In addition, you should handle the case where the create does not save (validation problem)
Upvotes: 2
Reputation: 4315
I suppose if you are using Devise+Omniauth , you could take a look at this more recent Railscast. There is a native support of OmniAuth in the new version of Devise gem .
Upvotes: 0