您好我的SQL和/或Rails Friends。
假设我们有两个型号:
class Hostel < ActiveRecord::Base
has_many :beds
end
class Bed < ActiveRecord::Base
belongs_to :hostel
end
当我的用户(旅馆所有者)尝试创建新预订时,参数会像这样:
{bed_id:12,start_date:" 2017-10-13",end_date:" 2017-10-15",...}
BED_ID 来自下拉菜单,显示所有Current_user的床名。ID随其余表单数据传递。现在,在BookingsController中,我必须手动确保黑客不会操纵 bed_id 变量到他们不拥有的床上。
class BookingsController < ApplicationController
def create
@bed = current_user.beds.where(id: params[:bed_id]).first
if @bed
# create hostel booking
else
# this happens when the user willfully changes the bed_id
# number using DevTools
end
end
我不介意以这种方式验证用户输入,但是我想知道是否有一种方法可以利用SQL和/或外键约束来确保用户不会使用不使用的床来创建预订'T属于他们?
这是一些pidgin sql,说明了我想要的东西。基本上,使数据库验证 bed_id 使用的 user_id 是Current_user的ID。
INSERT INTO bookings (start_date, end_date, bed_id, user_id)
VALUES ("2017-10-13", "2017-10-15", 12, 1)
UNLESS (SELECT * FROM beds WHERE id = 12).user_id != current_user.id
# what I'm doing above is verifying that bed #12 has a user_id that
# is the same as the current user's ID. That way, if a user
# manipulates the params, SQL catches it.
编辑:这是一个更好的问题:
在铁轨中,我可以打开控制台并手动创建新的预订:
Booking.new(user_id: 1, bed_id: 12, start: "2017-10-13", end: "2017-10-15")
和数据库将创建记录,即使具有ID#12的床不属于用户#1。无论如何是否可以使SQL加强这些约束?
我知道这不是问什么,而是...我首选的解决方案是在轨道上进行操作,这使您可以更好地控制并独立于平台。
(对不起,我不能轻易验证它,但应该给您这个想法)
class BookingsController < ApplicationController
before_action :check_authorisation, only: :create
def check_authorisation
unless current_user.beds.where(id: params[:bed_id]).first
flash[:danger] = "You are not authorised to access this section"
redirect_to home_url # halts request cycle need to adjust home_url to appropriate
end
end