Yurii Cherniavskyi
Joined
50 Experience
0 Lessons Completed
0 Questions Solved
Activity
First of all the logic of my app. The user could have several profiles situationally, such as blogger, advertiser or manager and act with different profile different role. But during public registration, it could register only as blogger or advertiser. Add manager profile to the user can only admin.
So my main models:
So my main models:
class User < ApplicationRecord
has_one :profile_manager, :class_name => 'Profile::Manager', dependent: :destroy, autosave: true
has_one :profile_blogger, :class_name => 'Profile::Blogger', dependent: :destroy, autosave: true
has_one :profile_advertiser, :class_name => 'Profile::Advertiser', dependent: :destroy, autosave: true
accepts_nested_attributes_for :profile_manager,
:profile_blogger,
:profile_advertiser
end
class Profile::Base < ApplicationRecord
self.abstract_class = true
belongs_to :user
end
class Profile::Blogger < Profile::Base
end
class Profile::Advertiser < Profile::Base
end
class Profile::Manager < Profile::Base
endTo apply limitation on registration I create one more model with virtual attribute profile:
class RegistrableUser < User
DEFAULT_PROFILE_MODEL_NAME = Profile::Blogger.model_name
AVAILABLE_PROFILES_MODEL_NAMES = [Profile::Blogger.model_name, Profile::Advertiser.model_name]
self.table_name = base_class.table_name
attribute :profile, :string, default: DEFAULT_PROFILE_MODEL_NAME.param_key
validates :profile, inclusion: {in: AVAILABLE_PROFILES_MODEL_NAMES.map(&:param_key),
message: "%{value} is not a valid profile"}
before_create :profile_decode
private
def profile_decode
case self.profile
when Profile::Blogger.model_name.param_key
self.build_profile_blogger(active: true)
when Profile::Advertiser.model_name.param_key
self.build_profile_advertiser(active: true)
end
end
endSeams it operates correctly. But I am not sure is it the correct implementation of such functionality in general and conversion virtual attribute to real profile property (by before_create hook) in particular case.