[英]Inject attribute from association table into the associated record?
I have the following model in my Rails app: 我的Rails应用中有以下模型:
class Course < ActiveRecord::Base
has_many :memberships
has_many :members, through: :memberships, class_name: 'User'
end
While course.members
successfully returns the course's members, I don't get access to the Membership
model which has a role
attribute. 虽然course.members
成功返回了课程的成员,但我无法访问具有role
属性的Membership
模型。
How do I find the user role without having to find the Membership
given my Course
and User
? 如何找到用户角色而不必找到给定Course
和User
的Membership
? Can I inject the role
attribute to User
somehow in the context association? 我可以在上下文关联中以某种方式向User
注入role
属性吗?
User model: 用户模型:
class User < ActiveRecord::Base
has_many :memberships, dependent: :destroy
has_many :courses, through: :memberships
end
Here's a solution, not the most beautiful and idiomatic though 这是一个解决方案,虽然不是最漂亮,最惯用的
class Course < ActiveRecord::Base
has_many :memberships
def members
User.joins(:memberships).where(id: memberships.ids).select('users.*, memberships.role')
end
end
A better approach, suggested through the comments: 通过评论提出了一种更好的方法:
has_many :members, -> { select('users.*, memberships.role') }, class_name: 'User', through: :memberships, source: :user
I had the exact same problem, and couldn't find any way to fetch the intermediate association without explicitly finding it. 我遇到了完全相同的问题,并且在没有明确找到它的情况下找不到任何方法来获取中间关联。 It's not that ugly, though: 但是,它并不那么丑陋:
class User < ActiveRecord::Base
has_many :memberships, dependent: :destroy
has_many :courses, through: :memberships
def role_in(course)
memberships.find_by!(course: course).role
end
end
user.role_in(course)
# => "teacher"
I think dynamically storing the contextual role
depending on what Course
is used is not a good idea. 我认为根据所使用的Course
动态存储上下文role
不是一个好主意。 It feels hacky to me because the attribute value becomes set implicitly rather than by explicit execution. 对我来说,这很麻烦,因为属性值是隐式设置的,而不是显式执行的。 A User
would appear different depending on where and how it's instantiated, despite representing a row in the database. 尽管实例化了数据库中的一行,但根据实例化的位置和方式, User
看起来会有所不同。
I would instead implement something like below: 我将改为执行以下内容:
class User
def course_role(course)
memberships.find_by_course(course).role
end
end
class Course
def user_role(user)
members.find_by_user(user).role
end
end
This way, it's explicit that calling methods on either the User
or Course
to get the role depends on the respective memberships they are associated with. 这样,很明显,在User
或Course
上调用方法来获取角色取决于与它们关联的各自成员身份。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.