【问题标题】:Retrieve users from serialize-array of ids从 id 的序列化数组中检索用户
【发布时间】:2023-03-08 17:26:01
【问题描述】:

我的 Rails 应用程序有一个小功能,用户可以参考其他用户。为此,我需要在 user 表中有一个简单的列来存储引用用户的 id。然后我使用 id 来检索和显示引用的用户。

我认为Serialize 是最好的选择,但我无法从当前看起来像21,22,23,24,25 的数组中检索所有 id。

目前我找到的用户有:

  @user = User.find(params[:id])
  @references = User.find(@user.references)

但在我看来,例如@references.name,只有第一个出现。这似乎是我所能做的,因为每个块都会抛出一个未定义的方法错误。

有什么想法吗?此外,如果有比序列化更有效的方法来实现这一点,我会全神贯注。欢迎并赞赏所有对此的见解。

【问题讨论】:

  • 顺便说一句,如果User.find(@user.references) 返回多个实例,那么您随后的@references.name 将抛出一个未定义的方法错误,因为您正在尝试获取@ 987654327@ ActiveRecord 关系的属性。

标签: ruby-on-rails activerecord serialization ruby-on-rails-4


【解决方案1】:

您可能希望使用 关联 来解决此问题,如 http://guides.rubyonrails.org/association_basics.html

中所述

但是,如果您没有将 references 声明为“序列化”字段,则可以解释您遇到的问题,因为 SQL 会将 '21,22,23,24,25' 匹配到 '21' .尝试以下操作以查看实际效果:

User.find('21,22,23,24,25')

并将其与以下内容进行比较:

User.find([21,22,23,24,25])

如果references 已正确序列化,您应该看到什么。

另请注意,序列化仅适用于 future 存储的值。如果您在数据库中有之前编写的内容,则在提取时将无法正确序列化。

【讨论】:

  • 在用户 HABTM 用户中?我的印象是这样一个简单的功能相当混乱。
  • 如在 HABTM 中(如果您想通过关系回溯)或 has_many through: 如果您不这样做。相反,我认为关联很干净,摆弄列表很麻烦,但我想这是主观的。
  • 哇,我已经尝试了所有方法,但它似乎不起作用。不过,我相信缺乏来自我的部分,因为我对序列化一点也不熟悉。但是,如果您说关联同样好,而不是更少,这就是我相信我会走的方式,因为我对它们了解更多并且想到它,has_many through: 可能对此很自然。即便如此,我认为重定向到解决方案是值得接受的答案。
  • 我不想让这个问题悬而未决。它确实应该与序列化属性一起使用。您是否确认您从@user.references 收到了一个数组?
  • 这实际上是我认为的错误,它似乎是字符串,即使我在 User 模型中实现了 serialize :references 并且列是 text 类型。这就是我认为需要的全部内容。
【解决方案2】:
@user = User.find(params[:id)
@references = User.where(id: @user.references).all

应该可以,例如:

[4] pry(main)> User.where(id: [1,2,3]).all.count
DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`). (called from __pry__ at (pry):4)
  User Load (3.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2, 3)
=> 3

【讨论】:

  • 嗯,很合乎逻辑,但似乎仍然只检索一个,即数组中的第一个。
  • 不,返回所有引用用户的数组:)
  • @dosadnizub 如果find(@user.references) 只给出1 个结果,那么where(id: @user.references) 将只给出1 个结果。
  • 我的,你是对的,我不知道它会这样做:) 但是,它确实返回了一个由存储在 user.references 中的 ID 引用的用户实例列表。你确定@user.references 没问题吗?否则代码会做它应该做的事情
  • 您需要专门向我发送您的 cmets,否则我不会收到通知,因为我不是 OP。实际上,如果@user.references 只是一个逗号分隔的字符串,wherefind 都只会返回 ID 与字符串中第一个整数匹配的 User 实例。
猜你喜欢
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多