В зависимости от того, с какой стороны вы пришли, вы можете сделать это следующими способами:
Visit
.group(:user_id, :building_id)
.pluck(:user_id, :building_id, 'AVG("visits"."end_at" - "visits"."start_at")')
.map { |*ids, visit_duration| [ids, visit_duration] }
.to_h
Создает хэш с комбинацией пользователя и идентификатора здания в качестве ключа и среднего времени посещения в качестве значения.
Если вы пришли от одного пользователя:
user.visits.group(:building_id)
.pluck(:building_id, 'AVG("visits"."end_at" - "visits"."start_at")')
.to_h
Или, если вы выходите из здания:
building.visits.group(:user_id)
.pluck(:user_id, 'AVG("visits"."end_at" - "visits"."start_at")')
.to_h
Надеюсь, вышесказанное вдохновит вас. Этот ответ работает только с идентификаторами, чтобы сделать запрос простым. Если вы хотите, чтобы весь экземпляр был установлен в качестве ключа, вы можете найти их с помощью отдельного запроса.
Примером этого может быть:
average_time = user.visits # ...
buildings = average_time.keys.zip(Building.find(average_time.keys)).to_h
average_time.transform_keys! { |building_id| buildings[building_id] }
# The simpler approach
#
# average_time.transform_keys!(&:Building.method(:find))
#
# results in a 1+N query