我的目标:
我尝试使用不同的个人资料创建两种不同类型的用户。
Barber
,Client
,BarberProfile
和ClientProfile
我的基础User
对象包含email
,password
等信息,以及Devise跟踪的所有其他字段。
我希望基本User
模型有一个Profile
来跟踪我希望所有用户拥有的所有基本信息。例如,first_name
,last_name
,avatar
等
我使用单表继承来创建两种不同类型的用户:Client
和Barber
。
我希望每种类型的用户都有一个与之关联的基础Profile
,然后分别拥有属于BarberProfile
和ClientProfile
的其他字段。
BarberProfile
会有Barber
所需的内容,但Client
不会。例如,bio
。 ClientProfile
会有Client
所需的内容,但Barber
不会。例如,hair_type
。
我目前拥有什么,以及我的问题:
如上所述,我已为User
和Profile
创建了一个表格。所以我可以致电user.profile.first_name
。我创建了一个BarberProfile
和ClientProfile
表,以便添加额外的字段。
如果用户类型为user.profile.bio
,我希望能够引用Barber
。但bio
不是基本资料的一部分。因此,在这种情况下,我必须创建关联的Profile
和以及关联的BarberProfile
以获取我需要的所有内容。我可以做user.profile.first_name
和user.barber_profile.bio
,但感觉很乱,而且我从基本上相同类型的模型中做出两种不同的关联。我觉得让BarberProfile
继承Profile
中的所有字段并在顶部添加自己的特定Barber
字段应该是一件简单的事情。
如何在Rails中执行此操作?
修改:我想要这样做的一个主要原因是,我可以在{{1}的同一表单中更新first_name
和bio
等内容}。同样,Barber
的同一表单中的first_name
和hair_type
。
答案 0 :(得分:1)
如果你想避免在Profile和Client / BarberProfile的用户上使用两个关联,我认为你应该使ClientProfile和BarberProfile扩展Profile(单表继承),并且每个"都有一个:barber_profile_data&#34 ; (我不知道怎么称呼它)。要修复长方法调用,可以使用委托方法。
class Barber > User
has_one :barber_profile
delegate :bio, to: :barber_profile
class Client < User
has_one :client_profile
delegate :first_name, to: :client_profile
class BarberProfile < Profile
has_one :barber_profile_data
delegate :bio, to: :barber_profile_data
class ClientProfile < Profile
has_one :client_profile_data
delegate :first_name, to: :client_profile_data
然后,当你执行&#34; @ barber.bio&#34;时,它应该在内部调用&#34; @ barber.barber_profile.barber_profile_data.bio&#34;。
答案 1 :(得分:0)
这听起来像是Multiple Table Inheritance的一个很好的用例。在MTI中,您可以使用其他表来装饰基本模型。
MTI的主要优点是clients
和barbers
表可以包含该类型与STI的特定列,这要求您按设计将所有内容填入users
(这就是为什么他们称之为单桌)。
create_table "barbers", force: :cascade do |t|
# only the specific attributes
t.text "bio"
end
create_table "clients", force: :cascade do |t|
# only the specific attributes
t.string "hair_type"
end
create_table "users", force: :cascade do |t|
t.string "email"
t.string "first_name"
t.string "last_name"
# ... all the other common attributes
t.integer "actable_id"
t.string "actable_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
这是ActiveRecord::ActsAs gem的一个例子。
class User < ApplicationRecord
actable
end
class Barber < ApplicationRecord
acts_as :product
end
class Barber < ApplicationRecord
acts_as :product
end
请注意,Barber
和Client
不应该是真正的子类。 ActiveRecord::ActsAs
代替“actable”类。
然后,您可以Barber.all
或Client.all
获取特定类型,或使用User.all.map(:specific)
获取所有类型的装饰用户。