因此,当用户的角色名称与Region的名称匹配时,我试图过滤,而在三个表之间的Arel连接上却卡住了。
用户具有名称,role_id,电子邮件等。用户具有has_many个角色。角色表具有ID和名称。区域具有名称,位置。地区不属于用户。
示例:
所以我想是用户加入区域名称匹配的区域
到目前为止我所拥有的:
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)登录,他只会看到太平洋西北地区的那些事件。
答案 0 :(得分:2)
我可能还没有完全理解您的问题,但是看来您应该能够执行以下操作:
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
这应该返回所有Event
,其中event.region_id
持有任何id
与Region
匹配的name
的{{1}}在name
的{{1}}中。
您可以从Specifying Conditions on the Joined Tables的docs了解更多信息。
我看到您有一种使用user
的方法。我将以非role
,非arel_table
,非arel_table
的方法来处理。
此外,我将在评论中重申docs的状态:
使用类方法是接受范围参数的首选方法。
答案 1 :(得分:0)
在百灵鸟上我尝试了,并且奏效了:
joins(:region).where(
Region.arel_table[:name].matches("%#{user&.role.name}%")
)