【问题标题】:Adding JOIN for associated tables [duplicate]为关联表添加 JOIN [重复]
【发布时间】:2013-03-06 20:22:52
【问题描述】:

我的 Organization 类如下所示:

has_many Students

我的学生班级如下所示:

has_many Klasses
belongs_to Organization

我的 Klass 类如下所示:

some field named : price
scope :top_expensive_classes, joins(:students).order('price DESC')
belongs_to Student

我的查询如下所示:

@results = Klass.top_expensive_classes.where(organization_id: params[:id]).limit(RESULT_SET_COUNT)

注意它以 Klass 开头,所以这就是问题所在,因为我在 where 类中搜索 organization_id 但那不在 Klass 中,它在 Student 类中,所以我应该以某种方式在某处引入一个 join 来解决这个问题,但是想不通。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.2 rails-activerecord


    【解决方案1】:

    我认为真正的问题是您的关联可能不正确。

    • 一个学生有很多课
    • 一个班级有很多学生

    但你拥有的是

    • 一个学生有很多课
    • 一个班级属于一个学生

    这真的没有意义(至少在我见过的任何情况下班级和学生互动)。您应该在 KlassStudent 之间创建多对多关系,而不是一对多关系。

    class Student < ActiveRecord::Base
      has_many :klasses, through: :student_klasses
      has_many :student_klasses
    end
    
    class Klass < ActiveRecord::Base
      has_many :students, through: :student_klasses
      has_many :student_klasses
    end
    
    class StudentKlass < ActiveRecord::Base
      belongs_to :student
      belongs_to :klass
    end
    

    一旦你有了这些正确的关联,你需要在Klass类的:students关联上调用.joins。没有范围也可以。

    Klass.joins(:students).where("students.organization_id = ?", params[:id]).order('price DESC').limit(RESULT_SET_COUNT)
    

    在 ActiveRecord 查询中阅读 the guide


    这是证明(使用上面的确切模型定义),关联的顺序确实重要。

    irb(main):001:0> s = Student.create(name: "Deefour")
      SQL (3.6ms)  INSERT INTO "students" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Fri, 08 Mar 2013 01:33:32 UTC +00:00], ["name", "Deefour"], ["updated_at", Fri, 08 Mar 2013 01:33:32 UTC +00:00]]
    => #<Student id: 1, name: "Deefour", created_at: "2013-03-08 01:33:32", updated_at: "2013-03-08 01:33:32">
    irb(main):002:0> kk = []
    => []
    
    irb(main):003:0> kk << Klass.create(title: "Klass 1")
      SQL (0.3ms)  INSERT INTO "klasses" ("created_at", "title", "updated_at") VALUES (?, ?, ?)  [["created_at", Fri, 08 Mar 2013 01:34:06 UTC +00:00], ["title", "Klass 1"], ["updated_at", Fri, 08 Mar 2013 01:34:06 UTC +00:00]]
    => [#<Klass id: 1, title: "Klass 1", created_at: "2013-03-08 01:34:06", updated_at: "2013-03-08 01:34:06">]
    
    irb(main):004:0> kk << Klass.create(title: "Klass 2")
      SQL (0.3ms)  INSERT INTO "klasses" ("created_at", "title", "updated_at") VALUES (?, ?, ?)  [["created_at", Fri, 08 Mar 2013 01:34:14 UTC +00:00], ["title", "Klass 2"], ["updated_at", Fri, 08 Mar 2013 01:34:14 UTC +00:00]]
    => [#<Klass id: 1, title: "Klass 1", created_at: "2013-03-08 01:34:06", updated_at: "2013-03-08 01:34:06">, #<Klass id: 2, title: "Klass 2", created_at: "2013-03-08 01:34:14", updated_at: "2013-03-08 01:34:14">]
    
    irb(main):005:0> s.klasses = kk
      Klass Load (0.1ms)  SELECT "klasses".* FROM "klasses" INNER JOIN "student_klasses" ON "klasses"."id" = "student_klasses"."klass_id" WHERE "student_klasses"."student_id" = ?  [["student_id", 1]]
      SQL (0.4ms)  INSERT INTO "student_klasses" ("created_at", "klass_id", "student_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Fri, 08 Mar 2013 01:34:29 UTC +00:00], ["klass_id", 1], ["student_id", 1], ["updated_at", Fri, 08 Mar 2013 01:34:29 UTC +00:00]]
      SQL (0.1ms)  INSERT INTO "student_klasses" ("created_at", "klass_id", "student_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Fri, 08 Mar 2013 01:34:29 UTC +00:00], ["klass_id", 2], ["student_id", 1], ["updated_at", Fri, 08 Mar 2013 01:34:29 UTC +00:00]]
    => [#<Klass id: 1, title: "Klass 1", created_at: "2013-03-08 01:34:06", updated_at: "2013-03-08 01:34:06">, #<Klass id: 2, title: "Klass 2", created_at: "2013-03-08 01:34:14", updated_at: "2013-03-08 01:34:14">]
    
    irb(main):006:0> Student.first.klasses.map(&:id)
      Student Load (0.2ms)  SELECT "students".* FROM "students" ORDER BY "students"."id" ASC LIMIT 1
      Klass Load (0.1ms)  SELECT "klasses".* FROM "klasses" INNER JOIN "student_klasses" ON "klasses"."id" = "student_klasses"."klass_id" WHERE "student_klasses"."student_id" = ?  [["student_id", 1]]
    => [1, 2]
    

    【讨论】:

    • 我还需要在那个范围内保留我拥有的 Join 吗?目前它说它找不到学生表。我们在某处有语法错误吗?也许应该是学生而不是学生?
    • 它说“找不到名为‘学生’的协会”
    • 您的关联似乎与应有的不完全一致。我已更新我的答案以帮助指导您。
    • 除非事情发生了变化,否则您的直通关系需要在连接关系之后定义。这里的响应没有这样做。
    • 这是错误信息;顺序无关紧要。
    猜你喜欢
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 2011-12-28
    • 2013-02-17
    相关资源
    最近更新 更多