首页 > 解决方案 > Rails 6获取2个时间戳的差异并分配给查询中的一个新字段

问题描述

我正在使用 postgresql 数据库开发 rails 6 应用程序,我必须计算调用时间。

我的数据库中有 2 个字段,一个是 answer_at(timestamp),另一个是 end_at(timestamp)

我使用以下查询,在该查询中,我需要 (end_at - answers_at) 和 call_duration 字段中的访问权限的区别

所以我可以通过 attr_accessor 访问 call_duration 字段,但我不知道如何获取差异并将其设置到查询中。

我原来的查询是

@in_app_calls = InAppCall.where("caller_user_id =? OR receiver_user_id =?", chat_user&.first&.id, chat_user&.first&.id)
           .group_by(&:call_type) unless chat_user.nil?

以下是我的数据库记录

<InAppCall id: 1, caller_user_id: 10, receiver_user_id: 61, call_type: "audio", call_answered: true, answered_at: "2020-07-16 04:24:17", end_at: nil, created_at: "2020-07-08 09:58:36", updated_at: "2020-07-16 04:24:17", on_going_updated_at: nil>

我可能会在 answer_at(timestamp) 或 end_at(timestamp) 字段中得到 nil 值,在这种情况下,我不会考虑该记录。

谁能帮我查询?

标签: ruby-on-railspostgresqlactiverecordtimestamp

解决方案


一个优雅的方法是使用 ActiveRecord 在您修改select列表时为您动态创建的虚拟属性。你可以这样做:

user_id = chat_user&.first&.id
@in_app_calls = InAppCall.
  select("in_all_calls.*, EXTRACT(EPOCH FROM end_at - answered_at)::int AS call_duration").
  where("caller_user_id = :user_id OR receiver_user_id = :user_id", user_id: user_id).
  where.not(answered_at: nil, end_at: nil).
  group_by(&:call_type) if user_id.present?

请注意,我使用AS call_duration=> ActiveRecord 创建的附加字段只是将其转换为attr_reader模型上的一个,因此您可以@in_app_calls[0].call_duration像使用任何常规列一样执行此类操作。

我还冒昧地清理了您的处理方式user_id——我希望这样是正确的,否则您应该可以毫不费力地将这一位恢复到原来的状态。


推荐阅读