【问题标题】:Compare the last element in Rails active record比较 Rails 活动记录中的最后一个元素
【发布时间】:2015-09-24 15:31:15
【问题描述】:

我有两个模型 Student 和 StudentRecord。 Student Record 属性中包含 start_date、end_date 和 class_course_id,属于 Student

scope = Student.eager_load(:student_record)

现在,我想获取最新(根据 start_date)student_record 的 class_course_id 与给定 class_course_id 相同的学生。类似:

scope = scope.where("student_records.order(start_date asc).last.class_course_id = ?", params[:class_course_id])

显然,上面的陈述是不正确的,但我希望它描述了我想要得到的。

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    下面应该做的

    Student.eager_load(:student_record).where("student_records.class_course_id = ?", params[:class_course_id]).order('student_records.start_date asc').last
    

    【讨论】:

    • 不,这不起作用。我认为它是在获取匹配项后对其进行排序的。
    【解决方案2】:

    使用Order by 子句并下降以获取最新日期.order("student_records.start_date DESC"),在where 子句中,记录将被过滤掉.where("student_records.class_course_id = ?", params[:class_course_id])where 会先出现,order by desc 会正确排序。

    scope.where("student_records.class_course_id = ?", params[:class_course_id]).order("student_records.start_date DESC")
    

    您可以通过.limit(5) 获取前 5 条记录,即最新的 start_dates。

    【讨论】:

    • 这没有得到想要的结果。匹配但不是最后一条记录的记录也会被提取
    • 所以使用.limit(1) scope.where("student_records.class_course_id = ?", params[:class_course_id]).order("student_records.start_date DESC").limit(1)
    【解决方案3】:

    如果你想要所有学生,那么这在活动记录中有点不重要。

    识别最后一个学生记录听起来很重要,可以从范围中受益:

    def self.latest_for_student
      where("not exists (select null from student_records sr2 where sr2.student_id = student_records.student_id and sr2.start_date > student_records.start_date)")
    end
    

    ...这意味着“返回相同student_id的student_records中不存在另一行的行,以及更大的start_date”

    或者……

    def self.latest_for_student
      where("student_records.start_date = (select max(start_date) from student_records sr2 where sr2.student_id = student_records.student_id)")
    end
    

    ... 这意味着“返回开始日期等于该学生 ID 的最大开始日期的行”

    那么你可以:

    class Student
      has_one :last_student_record, -> {merge(StudentRecord.latest_for_student)}, :class_name => "StudentRecord"
      has_one :last_class_course, :through => :last_student_record, :source => :class_course
    end
    
    class ClassCourse
      has_many :last_records_for_student, -> {merge(StudentRecord.latest_for_student)}, :class_name => "StudentRecord"
      has_many :students_having_as_last_course, :through => : last_records_for_student, :source => :student
    end
    

    那么你应该能够:

    @course.students_having_as_last_course
    

    有点复杂...可能是语法错误...如果有请告诉我。

    【讨论】:

    • 仍在尝试找出您的解决方案 :-)
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多