Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 基于订阅的rails查询限制_Ruby On Rails_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 基于订阅的rails查询限制

Ruby on rails 基于订阅的rails查询限制,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,我有一个相当复杂的问题,我可以提供一些帮助,因为我尝试的所有实现都有缺陷(Rails 4.2.1) 用户可以访问以下设备: create_table "devices", force: :cascade do |t| t.string "device_guid" t.datetime "created_at" t.datetime "updated_at" t.integer "user_ids" end 并且设备有许多数据条目: create_table "datas"

我有一个相当复杂的问题,我可以提供一些帮助,因为我尝试的所有实现都有缺陷(Rails 4.2.1)

用户可以访问以下设备:

create_table "devices", force: :cascade do |t|
  t.string   "device_guid"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.integer  "user_ids"
end
并且设备有许多数据条目:

create_table "datas", force: :cascade do |t|
  t.string   "device_id"
  t.datetime "start_time"
  t.datetime "end_time"
end
我们希望将所有查询限制为基于订阅的数据

create_table "subscriptions", force: :cascade do |t|
  t.integer  "device_id"
  t.integer  "user_id"
  t.datetime "start_date"
  t.datetime "end_date"
end
因此,有效地说,除非订阅允许,否则不应该访问数据

我希望在一个地方完成这个限制(而不是通过单独的方法来访问它),所以其他编写代码的人仍然要处理订阅限制。我不想使用第三方gem,因为数据非常敏感

我认为最明显的方法是在数据模型上设置一个默认范围,但我遇到了几个问题:
1)您无法从数据模型访问@user。我通过一个丑陋的黑客程序从模型中访问User.current解决了这个问题。
2)我不能使用当前用户,因为我们有冒充其他用户的管理员,需要查看数据。使用与#1相同的解决方法
3)同一用户和设备可以有多个日期不同的订阅。据我所知,没有任何方法可以执行ActiveRecord查询,该查询可以解释两个不同的日期范围(我使用arel_表解决了这个问题)。
4)这使得当我在rails控制台中时(理论上是通过API接口),所有查询数据的方法都会失败。如果没有User.current,我会忽略默认范围,但这显然是一个安全问题。

这是我当前的实现(在psuedocode中):

query=[]
订阅。每个do|
if(User.current.id==s.User\u id)

temp=Data.all.where(数据[:开始时间]>=s.start\u日期)。where(数据[:结束时间]
datas.device\u id
可能应该是一个整数一个整数。不要在模型级别上进行授权。我不想在这里反复无常,但你真的认为你的自制解决方案会比像CanCan或Pundit这样经过战斗测试的授权解决方案更安全吗?闻起来像是“未发明”综合症。基本上,原因是关于不应该在模型级别执行此操作的原因,是模型不应该知道应用程序环境,例如会话。这会导致可怕的复杂代码。相反,您可以执行Pundit所做的操作,并使用策略类,该类接受要授权的模型或范围以及用户,并返回true/false(或引发异常)@max我知道这似乎不是在这里发明的,但我使用了大量的gems,这只是我们希望重写的特定于安全的gems。这就是我们正在设计的。我喜欢gems,使用了大量的gems,但这不是我的要求,我个人同意这一点,对于这个特定的案例,这些数据非常敏感。你能给我多一点信息吗回答中关于政策类的陈述?如果我选择了这条路线,我会选择它作为正确答案-谢谢你的建议。
query = []
Subscription.each do |s|
  if (User.current.id == s.user_id)
    temp = Data.all.where(data[:start_time] >= s.start_date).where(data[:end_time] <= s.end_date).where(data[:device_id] == Device.find_by(id: s.device_id).device_guid)
    end
  end
  query += temp
end
default_scope { query }
<%= @user.device.find(1).data.all.count %>