Using Rails 5, I'm trying to implement Omniauth-Facebook and Clearance for user authentication.
Note: My code is exactly like this Gist
I've gotten it mostly working. However when using Facebook to register (ie a user has never visited the site), Rails throws an error saying Validation failed: User must exist
. I've narrowed down the problem to this block in the Gist:
def self.create_with_omniauth(auth_hash)
create! do |auth|
auth.provider = auth_hash["provider"]
auth.uid = auth_hash["uid"]
auth.token = auth_hash["credentials"]["token"]
end
end
When it hits that, it tries to create!
without a auth.user
object present, and fails. Here is the relevant code from the sessions
controller:
#-- Spectically, the line below
authentication = Authentication.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"]) || Authentication.create_with_omniauth(auth_hash)
#-- More code, for context
if authentication.user
user = authentication.user
authentication.update_token(auth_hash)
@next = root_url
@notice = "Signed in!"
else
user = User.create_with_auth_and_hash(authentication,auth_hash)
@next = edit_user_path(user)
@notice = "User created - confirm or edit details..."
end
The only thing I'm missing out of the Gist is the structure of his Authentications
table. Using the context clues I found, I created this table:
def change
create_table :authentications do |t|
t.string :provider
t.string :uid
t.string :token
t.references :user, foreign_key: true
t.timestamps
end
end
If any more information is needed, I'll provide what I can
In Rails 5 belongs_to is required by default http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html, so you'll get a validation error without it.
In this example you are trying to create Authentication
object without a User
, that's why you get "Validation failed: User must exist".
If you really want to create Authentication object without User, this should work:
class Authentication < ActiveRecord::Base
belongs_to :user, optional: true
end