Reputation: 43
I have two models one user and other is profile
class User < ActiveRecord::Base
has_one :profile
delegate :first_name, :last_name, :email, :phone, :location, to: :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
How can I validate user profile uniqueness as everytime for a same user it create many profiles after user signout and again signin by omniauth
like below
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.refresh_token = auth.credentials.refresh_token
user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name, email: auth.info.email, location: auth.info.location, phone: auth.info.phone)
user.save!
end
end
how to make unique priofile for a uniq user .
One way I did it
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.refresh_token = auth.credentials.refresh_token
user.auth_token = auth.credentials.token
user.instance_url = auth.credentials.instance_url
user.save!
if Profile.exists?(email: auth.info.email)
user.profile = Profile.where(email: auth.info.email).first
user.save
else
user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name,\
email: auth.info.email, location: auth.info.location, phone: auth.info.phone).save
end
end
end
but it is not a good way
I know it is very basic but want a best way..
Thanks in advance
Upvotes: 1
Views: 115
Reputation: 76774
You're getting confused between business logic and data integrity.
--
Your model (db) structure should be such that each user
should have one profile
. It doesn't matter if that user is logged in, eating curry or doing his laundry; he still has one profile:
#app/models/user.rb
class User < ActiveRecord::Base
has_one :profile
accepts_nested_attributes_for :profile
before_create :build_profile
end
#app/models/profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
end
The above creates a new profile
when the user
object is created. You already kind of have this functionality with your existing code.
The difference is that the above creates the data structure, which you can apply business logic to afterwards.
What you do with that data (business logic) is delegated from the fact each user has one profile:
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.refresh_token = auth.credentials.refresh_token
user.profile.first_name = auth.info.first_name
user.profile.last_name = auth.info.last_name
user.profile.email = auth.info.email
user.profile.location = auth.info.location
user.profile.phone = auth.info.phone
user.save!
end
end
Upvotes: 2
Reputation: 3477
You can add validation to User model. Check following example.
class User < ActiveRecord::Base
has_one :profile
delegate :first_name, :last_name, :email, :phone, :location, to: :profile
validate :profile_exists
private
def profile_exists
self.errors.add("profile", "already exists.") if self.profile.present?
end
end
Some edit for your code, check following.
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.refresh_token = auth.credentials.refresh_token
user.auth_token = auth.credentials.token
user.instance_url = auth.credentials.instance_url
user.save!
if user.profile.present?
user.profile.update(email: auth.info.email)
else
profile = user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name, email: auth.info.email, location: auth.info.location, phone: auth.info.phone)
profile.save
end
end
end
Upvotes: 0