【问题标题】:Inject attribute from association table into the associated record?将关联表中的属性注入关联记录?
【发布时间】:2015-07-08 20:14:36
【问题描述】:

我的 Rails 应用中有以下模型:

class Course < ActiveRecord::Base
  has_many :memberships
  has_many :members, through: :memberships, class_name: 'User'
end

虽然course.members 成功返回课程成员,但我无法访问具有role 属性的Membership 模型。

在给定我的CourseUser 的情况下,我如何在不查找Membership 的情况下找到用户角色?我可以在上下文关联中以某种方式将role 属性注入User 吗?

用户模型:

class User < ActiveRecord::Base
  has_many :memberships, dependent: :destroy
  has_many :courses, through: :memberships
end

【问题讨论】:

  • 会员模型长什么样子?

标签: ruby-on-rails ruby ruby-on-rails-4 associations


【解决方案1】:

这是一个解决方案,虽然不是最漂亮和惯用的

class Course < ActiveRecord::Base
  has_many :memberships

  def members
    User.joins(:memberships).where(id: memberships.ids).select('users.*, memberships.role')
  end
end

通过 cmets 建议的更好方法:

has_many :members, -> { select('users.*, memberships.role') }, class_name: 'User', through: :memberships, source: :user

【讨论】:

  • 谢谢,我会接受你的回答,因为你让我找到了更好的解决方案。我可以做到has_many :members, -&gt; { select('users.*, memberships.role') }, class_name: 'User', through: :memberships, source: :user,Rails 会处理剩下的事情。你能用这个更新你的答案吗?
【解决方案2】:

我遇到了完全相同的问题,并且在没有明确找到它的情况下找不到任何方法来获取中间关联。不过,它并没有那么难看:

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"

【讨论】:

    【解决方案3】:

    我认为根据使用的Course 动态存储上下文role 不是一个好主意。这对我来说感觉很奇怪,因为属性值是隐式设置的,而不是通过显式执行来设置的。 User 会根据实例化的位置和方式而有所不同,尽管它表示数据库中的一行。

    我会改为实现以下内容:

    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
    

    这样一来,调用UserCourse 上的方法以获取角色取决于它们所关联的相应成员资格。

    【讨论】:

    • 这也是我喜欢的意大利面。
    • 如果您感到被冒犯了,我很抱歉 - 我用可量化的解释替换了该描述。
    • 哦,我没有被冒犯。这就是你必须处理这个问题时通常会做的事情——这对我来说感觉像是意大利面条,因为虽然has_many :through 帮助我找到关联的用户,但我丢失了位于Membership 中的元数据。我认为注入行为不一定是错误的——我们有使用模型的装饰器非常棒——关联装饰器可以工作在我的用例中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多