【问题标题】:Rails belongs_to through associationRails belongs_to 通过关联
【发布时间】:2014-06-09 08:56:28
【问题描述】:

我正在尝试将新模型添加到现有模型网格中。现有的工作完美,但我无法让新的工作正常,我想知道该协会是否能够按照我试图使其工作的方式工作。更新:正如我刚刚被问到的那样:belongs_to through 是我在解决这个问题时读到的。如果它不存在,has_one through 会是正确的方法吗?我也试过了,还是不行。

这是现有的网格:

class Course
  has_many :users, through: :enrollments
  has_many :enrollments
end

class User
  has_many :courses, through: :enrollments
  has_many :enrollments
end

class Enrollment
  belongs_to :course
  belongs_to :user

  # has fields :user_id, :course_id
end

现在用户应该能够对他已完成的课程进行评分。 (如果他有,有一个带有他的 id 和课程 id 的注册。)我认为最好这样写:

class Course
  has_many :users, through: :enrollments
  has_many :enrollments
  has_many :ratings, through: :enrollments
end

class User
  has_many :courses, through: :enrollments
  has_many :enrollments
  has_many :ratings, through: :enrollments
end

class Enrollment
  belongs_to :course
  belongs_to :user
  has_one :rating

  # has fields :user_id, :course_id
end

class Rating
  belongs_to :enrollment
  belongs_to :course, through: :enrollment
  belongs_to :user, through: :enrollment
end

当我尝试在控制台中创建评级时,我收到以下错误:

User.first.ratings.create(text: "test", course_id: Course.first.id)
ArgumentError: Unknown key: through

更新 当我使用has_one through insted 时,出现以下错误:

ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection: Cannot modify association 'User#ratings' because the source reflection class 'Rating' is associated to 'Enrolment' via :has_one.

完全可以这样做吗?谢谢!

【问题讨论】:

  • belongs_to :through?真的存在吗?
  • 我在谷歌搜索时在某处读到它。如果不是,has_one :trough 会是正确的方法吗?我也试过了,但是没用。
  • 我认为没有 belongs_to :through in rails
  • 是的!也许你应该选择has_one :through
  • 也许你应该使用delegate

标签: ruby-on-rails activerecord associations


【解决方案1】:
class Course
  has_many :users, through: :enrollments
  has_many :enrollments
  has_many :ratings, through: :enrollments
end

class User
  has_many :courses, through: :enrollments
  has_many :enrollments
  has_many :ratings, through: :enrollments
end

class Enrollment
  belongs_to :course
  belongs_to :user
  belongs_to :rating

  # has fields :user_id, :course_id, rating_id
end

class Rating
  has_one :enrollment
  has_one :course, through: :enrollment
  has_one :user, through: :enrollment
end

注意:添加外键列

如果您在评级表中只有一/两列,请将它们合并到这样的注册中。

class Course
  has_many :users, through: :enrollments
  has_many :enrollments
end

class User
  has_many :courses, through: :enrollments
  has_many :enrollments
end

class Enrollment
  belongs_to :course
  belongs_to :user

  # has fields :user_id, :course_id, rating-columns...
end

【讨论】:

    【解决方案2】:

    结构

    也许你太复杂了

    class Enrollment
      belongs_to :course
      belongs_to :user
    end
    

    这意味着您有一个存储唯一记录的连接模型,引用courseuser。您的ratings 是基于usercourse 的吗?

    为什么不将rating 作为enrolment 模型的属性包含在内?:

    #enrolments
    id | user_id | course_id | rating | created_at | updated_at
    

    如果您给 rating 一个数值 (1 - 5),它将使您能够像这样对不同的注册进行评分:

    user = User.first
    course = Course.first
    
    user.enrolments.create(course: course, rating: 5)
    

    --

    评分

    当然,这是基于您当前的模型结构。

    如果您想通过userscourses 包含ratings(不绑定到enrolment),您可能希望使用称为join modeljoin model 或类似名称:

    #app/models/user.rb
    Class User < ActiveRecord::Base
       has_many :enrolments
       has_many :courses, through: :enrolments
       has_many :ratings, through: :courses, class_name: "CourseRating"
    end
    
    #app/models/course.rb
    Class Course < ActiveRecord::Base
       has_many :enrolments
       has_many :students, through: :enrolments, class_name: "User"
       has_many :ratings, class_name: "CourseRating"
    end
    
    #app/models/course_rating.rb
    Class CourseRating < ActiveRecord::Base
       belongs_to :course
       belongs_to :user
    end
    

    这将允许您调用:

    user = User.first
    user.courses.first.ratings
    

    【讨论】:

    • 是的,也许你是对的,我把它弄得太复杂了。我认为这很聪明;)感谢您的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多