Rails 4-如何在活动记录查询中为include()和joins()赋予别名 [英] Rails 4 - how to give alias names to includes() and joins() in active record querying

查看:116
本文介绍了Rails 4-如何在活动记录查询中为include()和joins()赋予别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何给例如一个别名 includes()
给出以下内容:




  • 用户:活动记录模型

  • 学生:活动记录模型,从用户(STI)继承

  • 教师:活动记录模型

  • 项目:活动记录模型



以下是一些示例:



首例(更多的STI协会)

  Project.all.includes(:students,:teachers).order('teachers_projects.name ASC')#教师订单
Project.all.includes(:students,:teachers).order('users.name ASC')#学生订单

Rails在SQL中为:teachers 自动使用别名 teachers_projects 。如何覆盖此内容,以便可以在SQL中使用别名 teachers 代替 teachers_projects :学生获得别名用户



此示例失败:

  Project.all.includes(:students,:teachers).order('teachers .name ASC')
Project.all.includes(:students,:teachers).order('students.name ASC')
Project.all.includes(:students,:teachers).order( 'students_projects.name ASC')

第二种情况(一个STI协会)



如果我仅使用:学生(不使用:教师)在方法 includes()中,Rails使用STI基类名称 users 的名称别名(不包含<$ c附加了$ c> _projects )用于:学生

  Project.all.includes(:students).order('users.name ASC')#对学生的订购

此示例失败:

  Project.all.includes(:students) .order('students.name ASC')
Project.all.inclu des(:students).order('students_projects.name ASC')

问题



可能存在以下内容:

  Project.all。 include(:students).alias(students::my_alias)

铁路别名跟踪器



https://github.com/rails/rails/blob/v4.2.0/activerecord/lib/active_record/associations/alias_tracker.rb#L59



测试应用



https://gist.github.com/phlegx/add77d24ebc57f211e8b



https://github.com/phlegx/rails_query_alias_names

解决方案

Arel实际上确实有一个lias方法。

  student_alias = Student.arel_table.alias(:my_student_table_alias)



:这将需要您使用更多手工制作的Arel并手动进行连接。如果您不习惯Arel中的联接,可能会变得有些复杂。

  student_alias_join = student_alias.create_on(
Project.arel_table [:primary_key] .eq(student_alias [:project_id])


Project.joins(
Project.arel_table.create_join(
student_alias,student_alias_join,Arel :: Nodes :: OuterJoin

).order(...)

应该执行类似的操作。
当然,使用:my_student_table_alias 作为参数将其放入某些Class方法中会使其更加整洁和可重用,因为在控制器中看起来有些混乱。 p>

How can I give an alias name for e.g. includes()? Following is given:

  • User: active record model
  • Student: active record model, inherits from User (STI)
  • Teacher: active record model, inherits from User (STI)
  • Project: active record model

Here some examples:

FIRST CASE (more STI associations)

Project.all.includes(:students, :teachers).order('teachers_projects.name ASC') # order on teachers
Project.all.includes(:students, :teachers).order('users.name ASC') # order on students

Rails uses automatically alias name teachers_projects for :teachers in the SQL. How can I overwrite this, so that I can use alias name teachers instead of teachers_projects in the SQL? :students gets alias name users.

This examples fails:

Project.all.includes(:students, :teachers).order('teachers.name ASC')
Project.all.includes(:students, :teachers).order('students.name ASC')
Project.all.includes(:students, :teachers).order('students_projects.name ASC')

SECOND CASE (one STI association)

If I use only :students (without :teachers) in method includes(), Rails uses name alias of the STI base class name users (without _projects attached) for :students:

Project.all.includes(:students).order('users.name ASC') # order on students

This examples fails:

Project.all.includes(:students).order('students.name ASC')
Project.all.includes(:students).order('students_projects.name ASC')

QUESTION

Might exist something like:

Project.all.includes(:students).alias(students: :my_alias)

RAILS ALIAS TRACKER

https://github.com/rails/rails/blob/v4.2.0/activerecord/lib/active_record/associations/alias_tracker.rb#L59

TESTING APP

https://gist.github.com/phlegx/add77d24ebc57f211e8b

https://github.com/phlegx/rails_query_alias_names

解决方案

Arel does actually have an alias method.

student_alias = Student.arel_table.alias(:my_student_table_alias)

caveat: this will require you to use even more handcrafted Arel and do the join manually. And the joins in Arel can get a bit complicated if you're not used to them.

student_alias_join = student_alias.create_on(
  Project.arel_table[:primary_key].eq(student_alias[:project_id])
)

Project.joins(
  Project.arel_table.create_join(
    student_alias, student_alias_join, Arel::Nodes::OuterJoin
  )
).order(...)

Something like this should do it. Of course putting this into some Class method with :my_student_table_alias as parameter would make it more tidy and reusable as this would look a bit messy in a controller.

这篇关于Rails 4-如何在活动记录查询中为include()和joins()赋予别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆