【问题标题】:How do I perform a where query on an enum attribute with a string rather than the ordinal value?如何使用字符串而不是序数值对枚举属性执行 where 查询?
【发布时间】:2016-01-05 00:52:20
【问题描述】:

所以我有一个具有如下枚举值的模型:

class Connection < ActiveRecord::Base
  enum request_status: { pending: 0, accepted: 1, rejected: 2, removed: 3 }
end

但是,我有一个参数值,我想设置并执行 where 查询 - 像这样:

@connections = current_user.all_connections.where(request_status: params[:request_status])

current_user.all_connections 返回一个 AR 对象(又名...它也是一个带有 where 调用的查询方法)。

我现在面临的问题是,上面的查询返回一个空集合。我相信的原因是每个API docs in Rails

枚举属性的条件必须使用 枚举。

鉴于params[:request_status] 将如下所示:

Parameters: {"request_status"=>"accepted"}

我将如何修改 where 查询以反映这一点?我知道另一种选择是将参数修改为序数值,而不是字符串,但我很好奇如何使用字符串值而不是序数值来实现这一点?

编辑 1

这里是服务器日志:

Started GET "/connections?request_status=accepted" for 127.0.0.1 at 2016-01-04 20:23:08 -0500
Processing by ConnectionsController#index as HTML
  Parameters: {"request_status"=>"accepted"}
  User Load (2.7ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 3  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (1.7ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = $1 LIMIT 1  [["user_id", 3]]
  Connection Load (2.0ms)  SELECT "connections".* FROM "connections"  WHERE "connections"."invited_user_id" = $1  ORDER BY "connections"."created_at" DESC  [["invited_user_id", 3]]
  Connection Load (1.8ms)  SELECT "connections".* FROM "connections"  WHERE "connections"."inviter_user_id" = $1  ORDER BY "connections"."created_at" DESC  [["inviter_user_id", 3]]
  Connection Load (2.2ms)  SELECT "connections".* FROM "connections"  WHERE (connections.invited_user_id = 3 OR connections.inviter_user_id = 3) AND "connections"."request_status" = 0  ORDER BY "connections"."created_at" DESC
  Rendered connections/index.html.erb within layouts/connections (0.3ms)
  Rendered connections/_header.html.erb (2.8ms)
  Rendered shared/_navbar.html.erb (61.2ms)
  Rendered shared/_footer.html.erb (3.2ms)
  Rendered layouts/application.html.erb (1142.4ms)
Completed 200 OK in 1184ms (Views: 1155.5ms | ActiveRecord: 10.4ms)

编辑 2

这是该控制器的索引操作。

  def index
    params[:request_status] = "pending" if params[:request_status].nil?
    @connections = current_user.all_connections.where(request_status: params[:request_status]).order(created_at: :desc).group_by { |c| c.created_at.to_date }
  end

奇怪的是,对于我单击的每个操作都应该发送正确的request_status,它仍然会发送带有request_status = 0 的 SQL。

我在控制器中注释掉了 params[:request_status] = 设置器,看看是否这样做,但不是。

什么可能导致这个问题?

这是另一个不同状态的日志:

Started GET "/connections?request_status=rejected" for 127.0.0.1 at 2016-01-04 21:30:29 -0500
Processing by ConnectionsController#index as HTML
  Parameters: {"request_status"=>"rejected"}
  User Load (2.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 3  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (1.5ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = $1 LIMIT 1  [["user_id", 3]]
  Connection Load (1.4ms)  SELECT "connections".* FROM "connections"  WHERE "connections"."invited_user_id" = $1  ORDER BY "connections"."created_at" DESC  [["invited_user_id", 3]]
  Connection Load (1.0ms)  SELECT "connections".* FROM "connections"  WHERE "connections"."inviter_user_id" = $1  ORDER BY "connections"."created_at" DESC  [["inviter_user_id", 3]]
  Connection Load (1.2ms)  SELECT "connections".* FROM "connections"  WHERE (connections.invited_user_id = 3 OR connections.inviter_user_id = 3) AND "connections"."request_status" = 0  ORDER BY "connections"."created_at" DESC
  Rendered connections/index.html.erb within layouts/connections (0.2ms)
  Rendered connections/_header.html.erb (2.5ms)
  Rendered shared/_navbar.html.erb (60.3ms)
  Rendered shared/_footer.html.erb (3.0ms)
  Rendered layouts/application.html.erb (1103.8ms)
Completed 200 OK in 1130ms (Views: 1112.5ms | ActiveRecord: 7.3ms)

【问题讨论】:

  • 提供SQL查询日志。它可以在我的控制台中使用字符串。可能是与 current_user 或 all_connections 方法连接。
  • @JoeHalfFace - 刚刚用服务器日志更新了问题。
  • AND "connections"."request_status" = 0 - 这表明问题的根源不是枚举。 id 为 3 的用户可能没有挂起的连接
  • @JoeHalfFace 很好。不知道为什么这样做。我刚刚用更多信息更新了这个问题。对于它的价值,它具有与 request_status = 0 相同的 SQL 查询,用于所有状态(即接受、待处理等)。
  • 枚举在 DB 架构中是否有默认值?

标签: ruby-on-rails ruby-on-rails-4 enums


【解决方案1】:

你可以使用Connection.request_statuses["pending"]得到0。

所以你可以像这样在查询中使用字符串:

@connections = current_user.all_connections.where(request_status: Connection.request_statuses[params[:request_status]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多