【问题标题】:Rails Arel Joins Connecting TablesRails Arel 连接连接表
【发布时间】:2019-10-01 16:30:04
【问题描述】:

因此,当用户的角色名称与区域名称匹配时,我正在尝试过滤,并且我卡在三个表之间的 Arel 连接上。

用户拥有姓名、角色 ID、电子邮件等。用户拥有多个角色。角色表有 id 和 name。地区有名称、位置。 Region不属于User。

例子:

  • John Smith id:20,role_id:15
  • 角色 ID:15,名称:太平洋西北地区
  • 地区 ID:5,名称:太平洋西北地区

所以我的想法是用户加入区域名称匹配的区域

到目前为止我所拥有的:

scope :for_user, lambda { |user|
 if user.super_admin?
  self
 else
  joins(:region).where(
  Region.arel_table[:name].matches(Role.arel_table[:id].eq(User.arel_table[:role_id]))
 )
 end
}

def viewable_by?(user)
 return user.super_admin? || user&.role.name == region.name
end

我在事件控制器中引用了 for_user 和 viewable_by

def index
 @events = search_event.paginate(page: params[:page])
end

def search_event
 Event.order(sortable_query)
    .for_user(current_user)
    .includes(:region)
    .advanced_search(
     params[:search],
     params[:region_id]
    )
end

def load_event
 @event = Event.find_by!(id: params[:id])
 raise DeniedError unless @event.viewable_by?(current_user)
end

我认为这可能是匹配问题,所以我也尝试了。出现了同样的问题:没有将 Symbol 隐式转换为 String。

这个想法是用户分配了一个角色,并且只能查看名称与该角色匹配的那些事件。

因此,如果 John Smith 登录,他只会看到太平洋西北地区的那些事件。

【问题讨论】:

  • 您要返回User 还是Role?在您的示例中,您是否尝试返回给定 Region 记录和“太平洋西北地区”的 name 的 John Smith 记录?您显示的代码在哪里?
  • 试图返回用户。我将使用控制器使用和可视方法更新问题。
  • 鉴于for_userEvent 模型上的一个方法,那么Region 以某种方式与Event 相关联?顺便说一句,docs 声明“使用类方法是接受范围参数的首选方式。”
  • 事件有belongs_to :region,可选:true。我可能需要为此删除可选项。
  • 我也有整个范围和viewable_by?模块中的方法,然后包含在事件模型中

标签: ruby-on-rails


【解决方案1】:

我可能没有完全理解您的问题,但您似乎应该能够执行以下操作:

Event < ApplicationRecord
  belongs_to :region

  class << self

    def for_user(user)
      return self if user.super_admin?
      joins(:region).where(region: {id: Region.where(name: user.role.name)})
    end

  end
end

这应该返回所有Events,其中event.region_id 包含任何Regionid,其中nameuserrole 中的name 匹配。

您可以从docsSpecifying Conditions on the Joined Tables 了解更多信息。

我看到您有一种使用arel_table 的方法。我将把它留在这里作为非arel_table、非lambda、非scope 方法。

另外,我将从我的评论中重申docs 状态:

使用类方法是接受范围参数的首选方式。

【讨论】:

    【解决方案2】:

    我尝试了一个百灵鸟,它奏效了:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 2019-01-22
      • 1970-01-01
      • 2022-01-20
      • 2012-03-01
      • 1970-01-01
      相关资源
      最近更新 更多