Christina Leuci
Christina Leuci

Reputation: 223

Initializing a class only when user signs up for the first time

I'm working on a Rails application that when the user signs up for the first time with facebook omniauth a new wardrobe will be created for that user.

I have two possible files that I think would work. I'll label the place I think

@wardrobe = Wardrobe.new
@wardrobe.save!

will work with a 'xx'

I suspect it must be in the User model when the user is first created using omniauth:

class User < ActiveRecord::Base
has_many :likes
has_many :outfits
has_one :wardrobe

def self.from_omniauth(auth_hash)
  where(auth_hash.slice(:provider, :uid)).first_or_initialize.tap do |user|
    user.provider = auth_hash.provider
    user.uid = auth_hash.uid
    user.name = auth_hash.info.name
    user.email = auth_hash.info.email
    user.image = auth_hash.info.image
    user.oauth_token = auth_hash.credentials.token
    user.oauth_expires_at = Time.at(auth_hash.credentials.expires_at)
    user.save!
  end
  xx
end

end

I also thought about putting it in the Sessions controller when the user creates a session but wouldn't that create a new Wardrobe each time they sign in:

class SessionsController < ApplicationController

def create
  @user = User.from_omniauth(env["omniauth.auth"])
  xx
  session[:current_user] = @user
  session[:user_id] = @user.id
  redirect_to wardrobe_index_path 
end
def destroy
  session[:user_id] = nil
  redirect_to root_url
end

protected

  def auth_hash
    request.env['omniauth.auth'] 
  end
end

Upvotes: 2

Views: 93

Answers (2)

Alexander
Alexander

Reputation: 2558

You can save state of user record(whether it new record or not) in local variable or create callback.

Example with callback:

class User < ActiveRecord::Base
  after_create :create_wardrobe
end

Example with check in from_omniauth method:

def self.from_omniauth(auth_hash)
  where(auth_hash.slice(:provider, :uid)).first_or_initialize.tap do |user|
    create_wardrobe = user.new_record?
    user.provider = auth_hash.provider
    user.uid = auth_hash.uid
    user.name = auth_hash.info.name
    user.email = auth_hash.info.email
    user.image = auth_hash.info.image
    user.oauth_token = auth_hash.credentials.token
    user.oauth_expires_at = Time.at(auth_hash.credentials.expires_at)
    user.save!
  end
  user.wardrope.create! if create_wardrobe
  user
end

Also, I think that so huge methods lead to fat models. Hence I suggest you to extract from_omniaut method to a service.

Upvotes: 3

Uri Agassi
Uri Agassi

Reputation: 37409

if @user has_one :wardrobe, why not simply create a wardrobe when one is not referenced by @user?

@wardrobe = @user.wardrobe
unless @wardrobe
  @wardrobe = Wardrobe.new
  @wardrobe.save!
  @user.wardrobe = @wardrobe
end

Upvotes: 1

Related Questions