我正在使用Cancancan在Rails 4中构建应用程序以进行角色授权。我有一个定义的能力适用于个人记录,但不适用于:index action。
我有一个名为' RVSP'的用户角色。 RVSP被分配WorkOrders
,RVSP将从中创建Record
。
class WorkOrder < ActiveRecord::Base
has_one :record
belongs_to :rvsp, class_name: "User"
end
class Record < ActiveRecord::Base
belongs_to :work_order
end
以下是我的问题:我希望RVSP用户能够阅读或更新Records
,其中WorkOrder
已分配给该RVSP。这是迄今为止的能力定义:
can [:read, :update], Record, Record.for_rvsp(user.id) do |record|
work_order = record.work_order
user.id == work_order.rvsp_id
end
范围Record.for_rvsp
就是这种怪异:
scope :for_rvsp, -> (rvsp_id) { where( work_order: { rvsp: { id: rvsp_id } } ) }
那么:如何定义Records
Record's
WorkOrder's
与当前用户的ID匹配的所有rvsp_id
的能力和/或查询?我怀疑它是某种形式的联合,但我是新手,并且以前没有做过。
P.S。我想到只添加一个created_by
列到Record
,但我已经通过PaperTrail获得了这一点,我将其用于审计跟踪。但就查询的难度而言,Record.versions.first.whodunnit
与Record.work_order.rvsp_id
大致相同。感谢您提供的任何建议!
P.P.S。我使用Postgres但是如果可以避免的话,我宁愿不做任何特定于数据库的SQL。
答案 0 :(得分:2)
我开始敲打连接,它似乎正在工作!我用以下类方法替换了上面的范围:
def self.for_rvsp(rvsp_id)
joins(:work_order).where(work_orders: {rvsp_id: rvsp_id})
end
我还在Ability.rb中整理了这个能力:
can [:read, :update], Record, Record.for_rvsp(user.id) do |record|
user.id == record.work_order.rvsp_id
end
因此,就索引操作而言,似乎需要在两个地方执行相同的操作:定义一个获取所需记录的范围,然后在块中定义该功能。范围确保您加载所有正确的记录,并且能力块授权它们。无论如何似乎对我有用!
答案 1 :(得分:0)
我知道这已经太晚了,但是您可以遍历CanCanCan中的关联。
map(function_to_apply, list_of_inputs)
x = map(lambda n: return len(n), object)
Top15['population'] = map(lambda n:'{:,}'.format(n),Top15['population'])
print(Top15['population'])