问题描述
我正在尝试编写一个ActiveRecord查询,该查询返回使用以下查询在某个课程中注册的所有学生:
def self.students_enrolled_in(course_id)
学生
.joins(:报名)
.joins(:sections)
.joins(:courses)
.where(sections: {course_id:course_id})
end
在rails控制台中的结果是:
似乎建立了关联。我究竟做错了什么?该查询实际上是不是意味着所有 join()
语句都必须与Student关联起来,还是应该ac找出关系链接?
教授显示页面:
< div class = col -md-8>
< h2 class = card-title><%= @ professor.name%>< / h2>
<%@ courses_taught.each做|当然| %>
< div class = card mb-4 card-header>
< img class = card-img-top src = http://placehold.it/750x300 alt =卡片图片上限>
< h3 class = card-text><%= course.title%>< / h3>
< / div>
< div class = card-body>
<%course.sections.enrollments.students.each do | student | %>
< p><%student.name%>< / p>
<%end%>
< / div>
<%end%>
< / div>
型号:
注册
班级注册< $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ : 班学生< ApplicationRecord
has_many:注册
结尾
教授:
class Section< ApplicationRecord
has_many:注册
所属名称:教授
所属名称:课程
validates_uniqueness_of:教授_id,范围::course_id
范围:by_professor_id, ->(prof_id){where('professor_id =?',prof_id)}
结尾
课程:
班级课程< ApplicationRecord
枚举状态:{规划:0,提供:1}
范围:提供,-> {where(status:1)}
范围:planning,-> {where(状态:0)}
属于:部门
has_many:sections
has_many:教授,通过::sections
验证:title, :number,:status,:description,在线状态:true
验证:description,长度:{in:10..500}
验证:title,:number,uniqueness:{case_sensitive:false}
def self.search(term)
if term
where('title LIKE?',%#{term}%)。order('title DESC')
else
订单('title ASC')
结束
结束
def self.taught_by(professor_id)
课程
.joins (:sections)
.joins(:professors)
.where(sections:{Professor_id:Professor_id})
.select('distinct course。*')
end
结束
模式:
ActiveRecord :: Schema.define(version:20171013201907)do
create_table courses,强制::cascade do | t |
t.string title
t.text description
t.string number
t.datetime created_at,null:false
t。 datetime updated_at,空:false
t.integer status,默认值:0
t.integer department_id
t.index [ department_id],名称: index_courses_on_department_id
end
create_table部门,强制::cascade do | t |
t.string名称
t.text描述
t.text main_image
t.text thumb_image
t.datetime created_at ,空值:false
t.datetime updated_at,空值:false
end
create_table enrollments,强制::cascade do | t |
t.integer section_id
t.integer student_id
t.datetime created_at,null:false
t.datetime updated_at,null:false
t.index [ section_id],名称: index_enrollments_on_section_id
t.index [ student_id],名称: index_enrollments_on_student_id
end
create_table教授,强制::cascade do | t |
t.string名称
t.datetime created_at,null:false
t.datetime updated_at,null:false
t.integer status,默认:0
t.integer department_id
t.text bio
t.index [ department_id],名称: index_professors_on_department_id
end
create_table sections,强制::cascade do | t |
t.integer number
t.integer max_enrollment
t.datetime created_at,null:false
t.datetime updated_at,null:false
t.integer教授_id
t.integer课程ID
t.string房间
t.index [ course_id],名称: index_sections_on_course_id
t.index [ professor_id, course_id],名称: index_sections_on_professor_id_and_course_id,唯一:true
t.index [ professor_id],名称: index_sections_on_professor_id
end
create_table students,强制::cascade do | t |
t.string名称
t。十进制 gpa
t.datetime created_at,null:false
t.datetime updated_at,null:false
end
create_table users,强制执行::cascade do | t |
t.string email,默认值:,null:false
t.string encrypted_password,默认值:,null:false
t.string name
t.string reset_password_token
t.datetime reset_password_sent_at
t.datetime remember_created_at
t.integer sign_in_count,默认值:0,null:false
t.datetime current_sign_in_at
t.datetime last_sign_in_at
t.string current_sign_in_ip
t.string last_sign_in_ip
t.datetime created_at,null:false
t.datetime updated_at,空:false
t.string角色
t.index [ email],名称: index_users_on_email,唯一:true
t.index [ reset_password_token],名称: index_users_on_reset_password_token,唯一:true
结束
结束
解决方案您正在过度申请 .joins
。尝试从内而外开始。首先,找到课程:
Course.find_by(id:course_id)
然后,找到与课程
相关的所有部分。无需在这里执行 join
Section.where(course :Course.find_by(id:course_id))
现在,您要加入:
Student.joins(:enrollments).where(注册人数:{section:Section.where(course:Course.find_by(id:course_id))}} )
我认为应该可以帮到您。但是,未经测试。因此,放手一试,看看它是否有效。
P.S .:尝试仅发布最相关的代码。整理一大堆无关紧要的东西并不是那么有趣。
I am trying to write an ActiveRecord Query that returns all students enrolled in a certain course with the following query:
def self.students_enrolled_in(course_id)
Student
.joins(:enrollments)
.joins(:sections)
.joins(:courses)
.where(sections: { course_id: course_id })
end
the result in the rails console is:
it seems that the association is made. what am I doing wrong? does the query actually mean that all the join()
statements have to relate back to Student, or should ac trace out the relational links?
Professor show page:
<div class="col-md-8">
<h2 class="card-title"><%= @professor.name %></h2>
<% @courses_taught.each do |course| %>
<div class="card mb-4 card-header">
<img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
<h3 class="card-text"><%= course.title %></h3>
</div>
<div class="card-body">
<% course.sections.enrollments.students.each do |student| %>
<p><% student.name %></p>
<% end %>
</div>
<% end %>
</div>
models:
enrollment
class Enrollment < ApplicationRecord
belongs_to :section
belongs_to :student
end
Student:
class Student < ApplicationRecord
has_many :enrollments
end
Professor:
class Section < ApplicationRecord
has_many :enrollments
belongs_to :professor
belongs_to :course
validates_uniqueness_of :professor_id, scope: :course_id
scope :by_professor_id, ->(prof_id) { where('professor_id = ?', prof_id) }
end
Course:
class Course < ApplicationRecord
enum status: { planning: 0, offered: 1 }
scope :offered, -> { where(status: 1) }
scope :planning, -> { where(status: 0) }
belongs_to :department
has_many :sections
has_many :professors, through: :sections
validates :title, :number, :status, :description, presence: true
validates :description, length: { in: 10..500 }
validates :title, :number, uniqueness: { case_sensitive: false }
def self.search(term)
if term
where('title LIKE ?', "%#{term}%").order('title DESC')
else
order('title ASC')
end
end
def self.taught_by(professor_id)
Course
.joins(:sections)
.joins(:professors)
.where(sections: { professor_id: professor_id })
.select('distinct courses.*')
end
end
Schema:
ActiveRecord::Schema.define(version: 20171013201907) do
create_table "courses", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.index ["department_id"], name: "index_courses_on_department_id"
end
create_table "departments", force: :cascade do |t|
t.string "name"
t.text "description"
t.text "main_image"
t.text "thumb_image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "enrollments", force: :cascade do |t|
t.integer "section_id"
t.integer "student_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["section_id"], name: "index_enrollments_on_section_id"
t.index ["student_id"], name: "index_enrollments_on_student_id"
end
create_table "professors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.text "bio"
t.index ["department_id"], name: "index_professors_on_department_id"
end
create_table "sections", force: :cascade do |t|
t.integer "number"
t.integer "max_enrollment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "professor_id"
t.integer "course_id"
t.string "room"
t.index ["course_id"], name: "index_sections_on_course_id"
t.index ["professor_id", "course_id"], name: "index_sections_on_professor_id_and_course_id", unique: true
t.index ["professor_id"], name: "index_sections_on_professor_id"
end
create_table "students", force: :cascade do |t|
t.string "name"
t.decimal "gpa"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "name"
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "roles"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
解决方案 You're over-applying .joins
. Try starting from the inside out. First, find the course:
Course.find_by(id: course_id)
Then, find all the sections associated with the course
. No need to do a joins
here:
Section.where(course: Course.find_by(id: course_id))
Now you do your join:
Student.joins(:enrollments).where(enrollments: {section: Section.where(course: Course.find_by(id: course_id))})
I think that ought to do the trick for you. But, untested. So, give it a go and see if it works.
P.S.: Try posting only the most relevant code. It's not so much fun to sort through a bunch of extraneous stuff.
这篇关于具有多个联接的ActiveRecord查询无法识别关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!