What is the correct way to convert virtual attribute to real one
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 end
To 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 end
Seams 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.