我有一个简单的案例,但是无法理解如何使用my-project-1.0-test.jar
来实现它。因此,我有一个类用户,它可以有一个ActiveRecord
,也有一个列profile
,这是一个枚举。看起来像这样
role
类似地,我有class User < ActiveRecord::Base
enum role: { manager: 1, writer: 2 }
has_one :profile
end
个用户Writer
和Manager
belongs_to
我正在努力指出用户的class Manager < ActiveRecord::Base
belongs_to :user
end
class Writer < ActiveRecord::Base
belongs_to :user
end
属性以根据角色枚举来更正编写者或管理者的个人资料。我不能使用多态关系,因为用户是父表,而配置文件表(编写者和管理者)依赖于它。
任何帮助都会得到帮助
答案 0 :(得分:1)
我认为您无法用动态“表名”(也称为动态模型)定义has_many
,主要是因为没有动态等效的SQL字符串来表示如下内容:
# Let's pretend that you have a `Post` model `belongs_to :user` and has an attribute `is_enabled:boolean`
# and that `User` `has_one :post`...
User.joins(:post).where(posts: { is_enabled: true })
# would generate an SQL
# User Load (0.6ms) SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "posts"."is_enabled" = true LIMIT 1
# ^ This works fine because `has_one :posts` always is mapped to the `posts` table
# but since you are asking for a dynamic one, then see an equivalent below
User.joins(:profile).where(":managers or :writers": { is_enabled: true })
# User Load (0.6ms) SELECT "users".* FROM "users" INNER JOIN "what_table" on "what_table"."user_id" = "users"."id" WHERE "what_table"."is_enabled" = true LIMIT 1
# ^ which as you could see does not have an exact SQL equivalent because it is
# "trying to" INNER JOIN on a "dynamic" table. You can do this per `User` record,
# because you know what to INNER JOIN with, but for a collection of `User` records,
# there is no such SQL "dynamic-table-name-matching" equivalent.
class User < ActiveRecord::Base
enum role: { manager: 1, writer: 2 }
has_one :manager
has_one :writer
def profile
case role
when 'manager' then manager
when 'writer' then writer
else raise NotImplementedError
end
end
# or if you prefer a dynamic-matching one:
# def profile
# send(role.to_sym)
# end
end
# rails console
user = User.first
puts user.profile
# => returns either <Manager...>, <Writer...>, or nil
“注意”是上面的“替代解决方案”,将profile
定义为方法,而不是关联,因此您将失去做INNER JOIN
s(无论如何,您可能都做不到;有关原因,请参阅我的TL; DR)