【发布时间】:2020-10-05 05:43:23
【问题描述】:
设置如下:
class Title
has_many :managed_rights
end
class ManagedRight
belongs_to :title
has_many :managed_right_countries
enumerize :territory_rights, in: [:all, :include, :exclude], default: :all
end
class ManagedRightCountry
belongs_to :managed_right
belongs_to :country
end
class Country; end
我想按国家/地区过滤标题,其中country_ids = [3, 5, 8, 9]。
- 所有案例
如果
title.managed_rights[0].territory_rights == :all选择这个标题 - 如果包含大小写
仅当
managed_right_countries中的任何一个在country_ids中时才选择,否则跳过。
title.managed_rights[0].territory_rights == :include
AND title.managed_rights[0].managed_right_countries IN country_ids
- 如果排除案例
选择所有标题,除非
managed_right_countries中的任何一个在country_ids中。
title.managed_rights[0].territory_rights == :exclude
AND title.managed_rights[0].managed_right_countries ALL NOT IN country_ids
这就是我对 Arel 的尝试:
managed_rights = ManagedRight.arel_table
managed_right_countries = ManagedRightCountry.arel_table
Title.left_outer_joins(managed_rights: :managed_right_countries)
.where(
# some other filters not related to "managed_rights"
managed_rights[:territory_rights].eq(:all)
.or(
managed_rights[:territory_rights].eq(:include)
.and(managed_right_countries[:country_id].in(country_ids))
.or(
managed_rights[:territory_rights].eq(:exclude)
.and(managed_right_countries[:country_id].not_in(country_ids))
)
)
).distinct
它适用于大多数情况,除非managed_right_countries.country_id 有一些不在country_ids 数组中的ID。上面的查询 :exclude 的含义仅在所有国家/地区都在数组中时才有效。
但是如果数组中有任何国家,我需要从结果中排除标题。
我怎样才能让它正常工作?
最好使用 AREL,但如果无法仅使用 Arel,原始 SQL(PostgreSQL) 也可以工作。
示例:
title_01 has `managed_rights[0].territory_rights = :all`
title_02 has `managed_rights[0].territory_rights = :include`
and `managed_rights[0].managed_right_countries = [1, 2]`
title_03 has `managed_rights[0].territory_rights = :exclude`
and `managed_rights[0].managed_right_countries = [2, 3]`
- 当按国家 [1] 过滤时,应选择所有 3 个标题(title_02 包含 1 个,但 title_03 不排除)
- 当按国家 [2] 时,仅应选择 title_01 和 title_02(因为排除了三分之三)
- 当按国家 [3] 时,仅应选择 title_01,因为 title_02 不包括 3,而 title_03 不包括 3
- 如果按空国家/地区过滤 [],则应显示所有三个
【问题讨论】:
标签: sql ruby-on-rails ruby postgresql activerecord