ruby-on-rails Ransack:两个过滤器各自独立工作,但不能一起工作,PG::UndefinedTable错误

olmpazwi  于 2023-01-18  发布在  Ruby
关注(0)|答案(1)|浏览(103)

在我的Rails 7应用中,我有公园用户。用户可以将公园标记为收藏访问过。我希望允许当前登录的用户根据他们是否收藏过公园和他们是否访问过公园来过滤公园。
目前,如果我只包含其中一个筛选器,这些筛选器就可以工作。但是如果我将两个筛选器都添加到表单中,则会出现以下错误:

ActiveRecord::StatementInvalid in Parks#index

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "favorited_users_parks"
LINE 1: ...rks"."id" AND NOT ("users"."id" NOT IN (44))) AND "favorited...

注意-这看起来非常非常类似于这里描述的问题,但我使用的是Rails 7,在这个线程中,他们声称这个问题在更新到Rails 6.1.0后得到了解决:https://github.com/activerecord-hackery/ransack/issues/1119
这个线程似乎有一些解决方案,为其他人工作,但我不明白如何使用连接和ransacks好到足以理解它如何应用到我自己的代码:https://github.com/activerecord-hackery/ransack/issues/542
下面是代码:

    • 视图/公园/过滤器. erb**
<div class="form-group">
   <%= f.label :favorited_users, 'Saved to favorites' %>
   <%= f.check_box :favorited_users_id_in, { class: "form-check-input" }, current_user&.id %>
</div>

<div class="form-group">
   <%= f.label :visited_users_id, 'Not yet visited' %>
   <%= f.check_box :visited_users_id_not_in, { class: "form-check-input" }, current_user&.id %>
</div>
    • 控制器/公园_控制器. rb**
class ParksController < ApplicationController
  def index
    @parks = @q.result(distinct: true).paginate(page:params[:page], :per_page => 24)
  end
end
    • 型号/park. rb**
class Park < ApplicationRecord
  has_many :visits, dependent: :destroy
  has_many :visited_users, through: :visits, source: :user

  has_many :favorites, dependent: :destroy
  has_many :favorited_users, through: :favorites, source: :user
end
    • 型号/用户. rb**
class User < ApplicationRecord
  has_many :visits, dependent: :destroy
  has_many :visited_parks, through: :visits, source: :park

  has_many :favorites, dependent: :destroy
  has_many :favorited_parks, through: :favorites, source: :park
end
    • 型号/收藏夹. rb**
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :park
end
    • 型号/访问. rb**
class Visit < ApplicationRecord
  belongs_to :user
  belongs_to :park
end
bq3bfh9z

bq3bfh9z1#

我还没有太深入地研究它,似乎这个问题仍然存在。解决方案只是坐在评论:

  • 网址:http://www.example.comgithub.com/activerecord-hackery/ransack/issues/542#issuecomment-245700688*
def index
  @q = Park.ransack(params[:q]) # this is just an object for the form
  @parks = search(Park.all)     # this is for actual search results
end

private

def search(collection)
  results = collection
  params[:q]&.each { |k, v| results = results.ransack(k => v).result }
  results
end

仅仅改变输入的顺序也是可行的。
您可能希望跳过复选框的隐藏输入,否则在未选中时发送0

#                                         vvvvvvvvvvvvvvvvvvvvv
<%= f.check_box :favorited_users_id_in, { include_hidden: false, class: "form-check-input" }, current_user&.id %>

# or like this                                                                           vvv
<%= f.check_box :favorited_users_id_in, { class: "form-check-input" }, current_user&.id, nil %>

相关问题