我在 Rails 3.0.9 的项目上使用 postgres tsearch。要进行 tsearch 查询,我需要在“from”子句中包含额外的 SQL。例如,假设我有这个模型:
class User < ActiveRecord::Base
has_one :profile
has_many :memberships
has_many :groups, :through => :memberships
end
我想对用户及其个人资料进行全文搜索。我可以这样做:
User.joins(:profile).where(
"(profiles.vectors @@ tsearch_query) or (users.vectors @@ tsearch_query)"
).from(
"to_tsquery('MYQUERY') as tsearch_query, users")
这会产生以下 SQL,并且工作正常:
"SELECT \"users\".* FROM to_tsquery('MYQUERY') as tsearch_query, users INNER JOIN \"profiles\" ON \"profiles\".\"user_id\" = \"users\".\"id\" WHERE ((profiles.vectors @@ tsearch_query) or (users.vectors @@ tsearch_query))"
但是如果我加入另一个连接,我会得到一些错误的 SQL:
User.joins(:profile).where(
"(profiles.vectors @@ tsearch_query) or (users.vectors @@ tsearch_query)"
).from(
"to_tsquery('MYQUERY') as tsearch_query, users").joins(:groups)
这是错误:
ActiveRecord::StatementInvalid: PGError: ERROR: missing FROM-clause entry for table "memberships" at character 108
: SELECT "users".* FROM to_tsquery('MYQUERY') as tsearch_query, users INNER JOIN "groups" ON "groups"."id" = "memberships"."group_id" WHERE AND ((profiles.vectors @@ tsearch_query) or (users.vectors @@ tsearch_query))
此查询中应该有三个连接语句。用户到配置文件、用户到成员资格和成员资格到组。仅包括最后一个连接,因此我们在没有更早连接的情况下引用成员表时会出错。
但是 AR::Relation 确实知道这两个连接:
irb(main)> _.send(:joins_values)
=> [:profile, :groups]
我认为问题在于添加“来自”范围调用。如果我把它剪掉,我就会得到我的两个连接。例如,我什至可以提供一个虚拟的“from”调用并得到相同的错误:
User.joins(:profile).from( "users" ).joins(:groups)
ActiveRecord::StatementInvalid: PGError: ERROR: missing FROM-clause entry for table "memberships" at character 68
: SELECT "users".* FROM users INNER JOIN "groups" ON "groups"."id" = "memberships"."group_id"
irb(main)> _.send(:joins_values)
=> [:profile, :groups]
删除“from”调用,效果很好:
User.joins(:profile).joins(:groups)
irb(main)> _.to_sql
=> "SELECT \"users\".* FROM \"users\" INNER JOIN \"profiles\" ON \"profiles\".\"user_id\" = \"users\".\"id\" INNER JOIN \"memberships\" ON \"users\".\"id\" = \"memberships\".\"user_id\" INNER JOIN \"groups\" ON \"groups\".\"id\" = \"memberships\".\"group_id\"
所以我不确定如何解决这个问题。
我的最终目标是能够对用户及其个人资料进行 tsearch 搜索,同时根据用户所在的组限制结果。
最佳答案
FWIW,这不是一个很好的答案,而是一个不错的解决方法:我可以通过将连接的实际 SQL 传递给 User.joins 而不是使用关系名称来让它工作。可能现在必须做。
与此同时,我想我会整理一份错误报告。
关于ruby-on-rails-3 - 链接 ActiveRecord::QueryMethods#from 和连接会产生错误的 SQL,缺少连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6498377/