简体   繁体   English

将属性从关联表注入到关联记录中?

[英]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 ? 如何找到用户角色而不必找到给定CourseUserMembership 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. 这样,很明显,在UserCourse上调用方法来获取角色取决于与它们关联的各自成员身份。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM