【问题标题】:IN query does not filter - Ruby on Rails 4IN 查询不过滤 - Ruby on Rails 4
【发布时间】:2016-07-08 09:51:57
【问题描述】:

我正在尝试按多个字段进行过滤。这些字段取自 ENUM 列表并放入复选框字段中,然后保存到数组中。我要过滤的 GET 请求如下所示:{"statuses" => ["active", "past_due"]}。我有一个查询范围,它应该按所选值进行过滤。我假设问题出在模型中。

型号:

scope :subscription_status, -> (statuses) {where :subscription_status => statuses}

控制器:

@users = User.where(nil)
@users = @users.subscription_status(params[:statuses]) if params[:statuses].present?

视图(html.haml):

= form_tag root_path, :method => 'get' do
    - @subscription_statuses.each do |status|
        = check_box_tag 'statuses[]', status
        = status
    = submit_tag "Filter", :name => nil

@subscription_statuses 包含 ENUM 列表。

我的其他过滤器的工作原理相同,但这个似乎不起作用。页面重新加载,发送 GET 参数,但没有过滤。

提前谢谢你。 :)

编辑:

@subscription_statuses = User.subscription_statuses.keys

这是一个字符串数组,数据库中的值保存为字符串。

【问题讨论】:

  • 您能否通过使用.to_sql 为调用添加后缀来输出您的代码生成的SQL 查询...例如:User.where(id: [1,2,3]).to_sql
  • 我不知道我是否理解你的问题,但这是我生成的: User.where(:subscription_status => ["trialing", "past_due"]).to_sql "SELECT @ 987654327@.* FROM users WHERE users.subscription_status IN (0, 0)"。你是对的,这里有一个问题,但我不知道为什么会这样翻译。如果我尝试在查询中输入 [1,2] 而不是“状态”,它不会显示任何内容,因为值保存为字符串...

标签: ruby-on-rails ruby-on-rails-4 search model-view-controller


【解决方案1】:

我想到了几件事。我之前也遇到过这种问题,所以这里只能假设你这里生成的statues

= check_box_tag 'statuses[]', status

是字符串。

所以当你将它们传递到参数params[:statuses] 时,它是一个字符串数组,但是当我们查询枚举类型时,如果它只是一个,你可以传入 sym 或字符串,它会正常工作。但是,当您有多个时,情况并非如此。

where :subscription_status => statuses 将生成类似WHERE users.subscription_status IN (0, 0, 0) 的sql,但所有subscription_statuses 都存储为整数类型的枚举类型。

所以在你的情况下,你必须先像这样找到它们对应的整数值

where(subscription_status: User.subscription_status.slice(*statuses).values)

您也可能会发现这个answer 也很有帮助

更新

由于您已经将 subscription_status 作为字符串存储在数据库中,因此在 User 模型中将列声明为枚举类型可能会产生冲突,从而导致无法生成所需的查询。简单地删除枚举类型声明可能会解决问题。

更新 2

所以我弄乱了 rails 控制台中的枚举类型。关于在传入字符串数组时出现IN (0, 0, 0) 之类的查询问题。当你传入一个符号数组时,它实际上显示IN (NULL, NULL, NULL)

我的猜测是,由于您已将其声明为枚举类型,因此它希望每个状态为整数,因此当您在生成查询之前尝试where(subscription_status: statuses) 时,它可能会执行statuses.map(&:to_i)。作为一个新发现(耶!)"hello".to_i => 0,而:hello.to_i => undefined method 因此(0, 0, 0)(NULL, NULL, NULL)。 (希望你能理解我这里乱七八糟的解释)

Possibility of mapping enum values to string type instead of integer

【讨论】:

  • 这不是问题... subscription_status 以字符串形式保存在数据库中,因为该数据库最初是使用 php/MySQL 创建的。另外,我忘了显示变量:@subscription_statuses = User.subscription_statuses.keys,其中包含一个字符串数组。
  • 但是你提到了@subscription_statuses contains the ENUM list,也许让我们看看你是如何在模型中定义subscription_status的?
  • 型号:枚举订阅状态:[:active, :trialing, :past_due, :deleted, :canceled]
  • 在这种情况下,如果您已经将它们存储为字符串,我认为您不需要将其声明为枚举类型。据我所知,rails 不允许将枚举类型列存储为整数以外的其他内容(see this post),我认为如果您删除枚举行,它应该可以与您已有的内容一起使用
  • 我尝试将值放入控制器而不是枚举,结果相同。
【解决方案2】:

我认为您最好在 rails 控制台中尝试此代码。事实证明,您的实现不应该有任何问题,但是查看生成的 SQL 将是理想的做法。您可以使用像 Byebug 这样的控制台调试器来帮助您调试请求并单步执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2018-04-20
    • 1970-01-01
    • 2012-12-16
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多