HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Creating a user profile from an omniauth hash

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
creatinguserprofilehashomniauthfrom

Problem

I have this code that creates (or updates) a user from an omniauth hash parameter:

def self.find_or_create_from_auth_hash(auth_hash)
    uid = auth_hash['uid']
    provider = auth_hash['provider']

    user = find_or_create_by(uid: uid, provider: provider)

    user.name = auth_hash['info']['name'] || ''
    user.email = auth_hash['info']['email']
    user.nickname = auth_hash['info']['nickname']
    user.avatar = auth_hash['info']['image'] || ''

    user.access_token = auth_hash['credentials']['token']

    user.location = auth_hash['extra']['raw_info']['location'] || ''
    user.company = auth_hash['extra']['raw_info']['company'] || ''
    user.member_since = auth_hash['extra']['raw_info']['created_at'] || ''

    user if user.save
  end


It is working, but it looks unpleasant. What can be changed in this piece of code, making it easier to read and/or beautiful?

Solution

The "default to empty string" bit should probably be done in the model. I.e. in a before_validation callback or similar.

You can also use Hash#slice to pluck out certain keys:

user = find_or_create_by(auth_hash.slice(%w(uid provider)))

user.assign_attributes(auth_hash['info'].slice(%w(name email nickname))
user.avatar = auth_hash['info']['image']

user.access_token = auth_hash['credentials']['token']

extra = auth_hash['extra']['raw_info']

user.assign_attributes(extra['raw_info'].slice(%w(location company)))
user.member_since = extra['raw_info']['created_at']


Alternatively, you could rewrite the keys (e.g. in a loop or using transform_keys) before using assign_attributes:

translations = { # could be a constant somewhere
  'image' => 'avatar',
  'token' => 'access_token',
  'created_at' => 'member_since'
}

attributes = auth_hash['info'].slice(%w(name email nickname image))
attributes.merge!(auth_hash['extra']['raw_info'].slice(%w(location company created_at)))
attributes['token'] = auth_hash['credentials']['token']

attributes.transform_keys! { |key| translations[key] || key }

user.assign_attributes(attributes)

Code Snippets

user = find_or_create_by(auth_hash.slice(%w(uid provider)))

user.assign_attributes(auth_hash['info'].slice(%w(name email nickname))
user.avatar = auth_hash['info']['image']

user.access_token = auth_hash['credentials']['token']

extra = auth_hash['extra']['raw_info']

user.assign_attributes(extra['raw_info'].slice(%w(location company)))
user.member_since = extra['raw_info']['created_at']
translations = { # could be a constant somewhere
  'image' => 'avatar',
  'token' => 'access_token',
  'created_at' => 'member_since'
}

attributes = auth_hash['info'].slice(%w(name email nickname image))
attributes.merge!(auth_hash['extra']['raw_info'].slice(%w(location company created_at)))
attributes['token'] = auth_hash['credentials']['token']

attributes.transform_keys! { |key| translations[key] || key }

user.assign_attributes(attributes)

Context

StackExchange Code Review Q#94260, answer score: 6

Revisions (0)

No revisions yet.