我有一个与my_ersy MyVersions关联的用户。 每次在User中更改“profile_id”或“state”列时,都会创建一个MyVersion。 MyVersion有以下列:
user_id, object_changed (profile_id or state), before, after
我需要查找处于活动状态且在特定时间具有特定配置文件的用户。意思是,在相关的my_versions中发生这种情况时查找所有用户:
my_versions是在日期之前创建的,其中:object_changed是'州'并且在该时间范围内: 1.1然后(不是AND)找到最后一个,只有当以下值为'活动'时才选择用户
my_versions是在日期之前创建的,其中:object_changed是'profile_id'并且在该时间范围内:
2.1那么找到最后一个并且只选择用户,如果:after的值为'1'
编辑1:显然我越来越接近但仍然不确定这是否能满足我的需求:
active_user_ids = User.joins(:my_versions).merge(MyVersion.where(
"my_versions.created_at = (SELECT MAX(created_at) from my_versions WHERE
user_id = users.id AND created_at < '2016-01-01' AND object_changed = 'state')
AND my_versions.after = 'activo'")).pluck(:id)
现在我拥有当时处于活动状态的所有用户IDS(是吗?)。然后我可以对配置文件执行相同操作,但也传递以前的IDS以正确组合结果:
active_and_right_profile =
User.joins(:my_versions).merge(MyVersion.where(
"my_versions.created_at = (SELECT MAX(created_at) from my_versions WHERE
user_id = users.id AND created_at < '2016-01-01' AND object_changed = 'profile_id')
AND my_versions.after = 1")).where(id: active_user_ids)
它看起来不漂亮,我不确定我是否在规格中得到了我上面描述的内容。第一次测试似乎是正确的,但我有很多疑问,因为我不理解查询的某些部分:
它看起来如何?有没有办法让它只用一个查询更好?有没有办法避免搜索我上面提到的确切的created_at值?
谢谢!
以前的尝试:
我试过这个:
Class User...
scope :active_at, -> (date) {
joins(:my_versions).merge(MyVersion.on_state.before_date(date)
.where("my_versions.created_at = (SELECT MAX(created_at) FROM my_versions WHERE user_id = users.id AND after = 'activo')"))
}
但这会创建以下查询:
SELECT `users`.* FROM `users` INNER JOIN `my_versions` ON `my_versions`.`user_id` = `users`.`id` WHERE `my_versions`.`object_changed` = 'state' AND (my_versions.created_at < '2016-01-31') AND (my_versions.created_at = (SELECT MAX(created_at) FROM my_versions WHERE user_id = users.id AND after = 'activo'))
这不是我需要的。