Ruby on rails 4 rails 4中的引用函数

Ruby on rails 4 rails 4中的引用函数,ruby-on-rails-4,Ruby On Rails 4,我只是不理解Rails 4中的新references()函数 我在这里读定义: 这是一个英语问题,但我还是不清楚。 这个新功能的目标是什么?(以前没有它,代码运行得很好) 我必须始终为includes()的每个表添加引用吗 谢谢我认为这是为了当您急于加载关联并且使用字符串条件时使用的。因为Rails不希望必须解析where子句中的原始SQL来确定您正在做什么,所以引用旨在使查询中发生的事情更加明确 Group.includes(:users).where('users.first_name =

我只是不理解Rails 4中的新references()函数 我在这里读定义:

这是一个英语问题,但我还是不清楚。 这个新功能的目标是什么?(以前没有它,代码运行得很好)

我必须始终为includes()的每个表添加引用吗


谢谢

我认为这是为了当您急于加载关联并且使用字符串条件时使用的。因为Rails不希望必须解析where子句中的原始SQL来确定您正在做什么,所以
引用
旨在使查询中发生的事情更加明确

Group.includes(:users).where('users.first_name = ?', 'John')
如果你这样做的话,你应该得到一些不赞成的警告。但是,如果使用哈希语法,则不应得到弃用警告:

Group.includes(:users).where(users: { first_name: 'John' })
因此,要修复第一个警告中的弃用警告,您需要向其添加
引用(:users)

Group.includes(:users).where('users.first_name = ?', 'John').references(:users)

当使用包含时,Rails通常会单独加载结果。例如,如果你

Post.includes(:comments)
它将发出一个查询以加载帖子,然后发出另一个查询以加载带有帖子id的评论

例如,如果您想执行以下操作,它将生成一个联接

Post.includes(:comments).where(comments: { user_id: 44})
其中一个条件取决于相关表。但是,如果您要使用

Post.includes(:comments).where('comments.user_id = ?', 44)
您将在Rails 4中得到一个错误。任何时候使用SQL代码段引用条件中的关系时,都必须使用
引用
。要解决上述问题,我们需要

Post.includes(:comments).where('comments.user_id = ?', 44).references(:comments)

当然,另一个选项是不要在条件语句中使用SQL片段,如第二个代码示例,但并不总是可以避免它们。

查询方法引用用于指示关联由SQL字符串引用,因此可以通过单独加载来连接。从Rails 4.1开始,添加包含引用的字符串条件将导致引发异常

下面是一个选择所有团队的示例,其中有一个名为Nishant的成员:

>> Team.includes(:members).where('members.name = ?', 'Nishant')
SQLite3::SQLException: no such column: members.name: SELECT "teams".*
FROM "teams" WHERE (members.name = 'Nishant')
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column:
members.name: SELECT "teams".* FROM "teams" WHERE (members.name =
'Nishant')
...
为了让上面的示例在Rails 4.1中工作,我们必须使用要加入的关联的名称包含查询方法引用

Team.includes(:members).where("members.name = ?", 'Nishant').references(:members)
但是,如果将哈希语法与关联条件一起使用,它仍将执行
左外部联接
,而不会引发任何异常:

Team.includes(:members).where(members: { name: 'Nishant' })
请注意,在包含的关联上排序字符串SQL片段仍将以相同的方式工作,而无需 参考文献:

Team.includes(:members).order('members.name')

我希望这会对您有所帮助。

好的,所以每次查询中有表名时,只要添加引用即可(如果是字符串)。这是这种情况的重要部分。比如,如果您使用的是基于散列的语法,那么就不需要了。