轨道Arel_table通过作用域连接多个表



我正在按角色在页面上进行过滤。因此,如果用户super_admin按其角色显示其他所有内容,其中角色通过两个表匹配。

用户示例:

  • 用户: 约翰·史密斯
  • 角色:太平洋西北地区

区域示例:

  • 区域: 太平洋西北部
  • 地点:西雅图、波特兰、博伊西

如果 John 登录到"查看事件",他应该只看到那些位置位于区域内的事件。所以假设波特兰有一个事件,那么约翰会看到它。

用户has_many角色、区域has_many位置。事件belongs_to位置和区域,但可选。

现在,这适用于将用户的角色连接到区域:

scope :for_user, lambda { |user|
if user.super_admin?
self
else
joins(:region)
.where(Region.arel_table[:name].matches("%#{user&.role&.name}%"))
end
}

所以 Location.name,Location.region_id = Region.id,Region.name = Role.name,Role.id = User.role_id。

我想我可以尝试这样的事情:

joins(:location)
.where(Location.arel_table[:region_id]).matches("%#{region.id}")
.joins(:region)
.where(Region.arel_table[:name].matches("%#{user&.role&.name}%"))

然而,这给出了:

不支持的参数类型:#

因此,假设可排序表具有位置和区域。如何根据与位置名称匹配的用户角色对其进行筛选?

编辑:

我想我可以用以下内容来切换它:

region = Region.find_by(name: user&.role&.name)
if region.present?
joins(:location)
.where(location_id: region.location_ids)
end

但是,这将显示所有位置。我觉得有点接近。所以我尝试了:

region = Region.find_by(name: user&.role&.name)
if region.present?
location = region.where(location_id: region.location_ids)
return true if location.present?
end

失败了,所以我尝试了:

region = Region.find_by(name: user&.role&.name)
list_locations = []
Location.all.each.do |loc|
list_locations << loc.name if loc.region_id == region.id && region.present?
end
self if list_location.present?

这最终只是显示一切。

把它留在这里以防它对某人有帮助:

region = Region.find_by(name: user&.role&.name)
if region.present?
joins(:location)
.where(location_id: region.location_ids)
end

这实际上奏效了。我更新了我的视图以显示位置&.region&.name,并注意到它正在过滤,我只有太多的页面,它似乎不起作用。

最新更新