按连接 table 属性排序时出现 Ransack 错误:多次指定 table 名称 "users"

Ransack error when sorting by joined table attribute: table name "users" specified more than once

当点击 table header 按 user_email 排序(见视图)时,它尝试 运行 的查询(见控制台输出)有一个重复left join users on users.id = invites.user_id.

这似乎是导致问题的原因,但我不确定如何避免它。

错误:

ActiveRecord::StatementInvalid in Admin::Invites#index
PG::DuplicateAlias: ERROR:  table name "users" specified more than once

控制台输出:

: SELECT  
    invites.id,
    invites.email,
    users.id as user_id,
    users.email as user_email FROM "invites" 
  LEFT OUTER JOIN "users" ON "users"."id" = "invites"."user_id" 
  left join users on users.id = invites.user_id 
  ORDER BY "users"."email" ASC LIMIT  OFFSET ):

控制器

@q = query.ransack(params[:q])
@invites = @q.result.page params[:page]

query控制器调用的方法

def query
  Invite.select('invites.id,
                 invites.email,
                 users.id as user_id,
                 users.email as user_email')
  .joins('left join users on users.id = invites.user_id')
end

查看

<th><%=sort_link(@q, :email, 'Sendee Email') %></th>
<th><%=sort_link(@q, :user_email, 'Sender Email') %></th>

我是第一次尝试 Ransack(它很棒),但我很想以某种方式避免这个错误。

如有任何建议,我们将不胜感激。

更新

{"s"=>"user_email asc"}, "controller"=>"admin/invites", "action"=>"index"} permitted: false>

<table>
  <thead>
    <tr>
      <th><%= sort_link(@q, :email, 'Sendee Email') %></th>
      <th><%= sort_link(@q, :user_email, 'Accepted') %></th>
    </tr>
  </thead>
  <tbody>
    <% @invites.each do |i| %>
      <tr>
        <td><%= i.email %></td>
        <td><%= i.user_email %></td>
      </tr>
    <% end %>
  </tbody>
</table>

...

你的问题是 .joins('left join users on users.id = invites.user_id'),你需要 change/remove 它因为它总是添加一个连接到你的 SQL 即使它不需要 - Ransack is smart enough to figure out when do the join based on params you pass to ransack. This question 可能帮助你,你必须重写query方法

第一个场景

{"s"=>"email asc"}, "controller"=>"admin/invites", "action"=>"index"} permitted: false>

生成SQL

SELECT  
  invites.id,
  invites.email,
  users.id as user_id,
  users.email as user_email FROM "invites" 
left join users on users.id = invites.user_id 
ORDER BY "users"."email" ASC LIMIT  OFFSET )

一个 JOIN - SQL 可以

第二种情况

{"s"=>"user_email asc"}, "controller"=>"admin/invites", "action"=>"index"} permitted: false>

生成SQL

SELECT  
  invites.id,
  invites.email,
  users.id as user_id,
  users.email as user_email FROM "invites" 
LEFT OUTER JOIN "users" ON "users"."id" = "invites"."user_id" 
left join users on users.id = invites.user_id 
ORDER BY "users"."email" ASC LIMIT  OFFSET )

两个 JOIN - SQL 不好