Ruby on rails 每个用户的ActiveRecord查询';s电子邮件地址表中的最新电子邮件地址
我想跟踪用户更改电子邮件地址的情况,所以我创建了一个“用户”表,该表由“电子邮件”表引用。“用户”表的内容对于这个问题并不重要。“emails”表包含字符串“email”列以及常用的“id”、“user\u id”、“created\u at”、“updated\u at”列。当用户的电子邮件发生更改时,将向“电子邮件”表添加一条新记录,该表通过“用户id”引用用户。因此,任何给定的用户都可以在“电子邮件”表中有多个电子邮件地址,但只有最新的一个是相关的联系信息 模型的设置如下所示:Ruby on rails 每个用户的ActiveRecord查询';s电子邮件地址表中的最新电子邮件地址,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我想跟踪用户更改电子邮件地址的情况,所以我创建了一个“用户”表,该表由“电子邮件”表引用。“用户”表的内容对于这个问题并不重要。“emails”表包含字符串“email”列以及常用的“id”、“user\u id”、“created\u at”、“updated\u at”列。当用户的电子邮件发生更改时,将向“电子邮件”表添加一条新记录,该表通过“用户id”引用用户。因此,任何给定的用户都可以在“电子邮件”表中有多个电子邮件地址,但只有最新的一个是相关的联系信息 模型的设置如下所示: class
class User < ApplicationRecord
has_many :emails
end
class Email < ApplicationRecord
belongs_to :user
end
但这似乎给了我每个用户最早的电子邮件地址,而不是最新的。我目前正在使用Rails 5.1
任何帮助都将不胜感激。这并不漂亮,但是
sql = "SELECT *
FROM emails e1 WHERE (user_id,id) IN
( SELECT user_id, MAX(id)
FROM emails e2
GROUP BY user_id
)"
Email.find_by_sql(sql)
如果您确实需要使用created_at
来确定顺序,那么只要created_at
值是唯一的,您就可以将上面的id
替换为created_at
并获得相同的结果
但是,如果可能的话,我强烈建议您在表中添加一个is_primary标志,以允许用户清楚地表示他们希望联系的电子邮件地址。您还需要添加逻辑和验证,以确保每个用户\u id只有一封电子邮件\u primary=true
此更改还将消除您在此处被迫发现的嵌套分组查询的需要。可能有几种方法,您可以尝试以下方法:
Email.all.group(:user\u id).order(“max(emails.created\u at)DESC”)
试试这个
emails=Email.all.group(:user_id)
Ordered_emails = emails.sort_by &:created_at
这仍然是一个组中最早的记录,而不是最新的。这为每个用户提供了最早的电子邮件。我需要每个用户的最新电子邮件。然后在“emails=Ordered_emails.reverse!”末尾添加这一行。我很不愿意这么说,但添加“is_primary”标志可能是正确的。您的解决方案在mysql中工作,但在sqlite中不工作,我正在使用sqlite进行初始测试。“is_primary”标志可能是最兼容的解决方案。
emails=Email.all.group(:user_id)
Ordered_emails = emails.sort_by &:created_at