获取具有唯一属性id的所有数组对象

时间:2015-12-11 00:32:40

标签: ruby-on-rails ruby

我有一个与通知模式有has_many关系的用户模式,其notifier_id属性等于某些User.id

我尝试编写一些逻辑来获取已向某个用户发送通知的每个用户的最新通知列表,但我对最佳方法感到困惑。

我试过了:

@notifications = @user.notifications.uniq { |note| note.notifier_id }

但是它给了我所有现有的通知,没有过滤。

我找到一篇关于类似问题的SO帖子,其解决方案与此类似:

@notifications = @user.notifications.map { |note| note.notifier_id }
  .uniq
  .map{ |notifier_id| Notification.find(notifier_id) }

但这对我没有用,因为有许多通知具有相同的notifier_id

我能想到的唯一另一个选择是循环遍历所有User.notifications,将每个唯一notifier_id添加到一个数组,然后使用该数组构建另一个数组,只包含来自每个唯一通知程序的第一个通知,但我觉得应该有更好的方法来做到这一点。有吗?

更新:

这是生成的SQL:@user.notifications.select("DISTINCT notifications.notifier_id")

SELECT DISTINCT notifications.notifier_id FROM "notifications" WHERE "notifications"."user_id" = $1  ORDER BY "notifications"."created_at" DESC

更新:

这是我改编的解决方案:

inner = Notification.
  order(nil).
  select("DISTINCT notifications.notifier_id, notifications.*").
  where("notifications.user_id = ?", @user.id)
@notifications = Notification.from("(#{inner.to_sql}) notifications").
  order("notifications.created_at DESC")

这是它的SQL:

Notification Load (3.3ms)  SELECT "notifications".* FROM (SELECT DISTINCT notifications.notifier_id, notifications.* FROM "notifications" WHERE (notifications.user_id = 313)  ORDER BY "notifications"."created_at" DESC) notifications  ORDER BY "notifications"."created_at" DESC, notifications.created_at DESC

输出与@ user.notifications

相同

临时解决方案:

这可以实现我想要的,但我想使用SQL查询

notifiers = []
@user.notifications.each do |note|
  if note.notifier_id
    found = false
    notifiers.each do |notifier_id|
      if notifier_id == note.notifier_id
      found = true
        break
      end
    end
    if !found
      notifiers << note.notifier_id
    end
  end
end

notifiers.each do |notifier_id|
  @notifications << @user.notifications.find{|x| x.notifier_id == notifier_id}
end

1 个答案:

答案 0 :(得分:0)

使用DISTINCT根据notifier_id选择所有唯一身份通知。

inner = Notification.
  order(nil).
  select("DISTINCT notifications.notifier_id, notifications.*").
  where("notifications.user_id = ?", current_user.id)
Notification.from("(#{inner.to_sql}) notifications").
  order("notifications.created_at DESC")