如何在以下方案中验证模型。我们有三种模式,即帐户,时间日志和项目。帐户has_many项目和项目belongs_to帐户。
当用户创建时间日志时,他们可以从与该帐户关联的项目列表中进行选择,输入更多详细信息并保存日志。
我们的一位开发人员指出,在保存时间日志时以及如果将属于另一个帐户的项目的ID传递回控制器,可以操作返回控制器的代码,然后该项目名称在视图中可见。通过这种方式,您可以构建其他帐户项目的列表,这并不酷。
所以我想要实现的是验证正在保存的记录,以确保项目ID实际上是与current_account相关联的项目。
我将如何实现这一目标?
目前,这就是我构建时间日志的方式
def create
@log = @employee.time_logs.build(params[:employee_time_log])
@log.account_id = current_account.id
if @log.save
flash[:notice] = "Time log sucessfully saved."
redirect_to employee_time_logs_path(@employee)
else
render :form
end
end
,时间日志模型如下所示
class EmployeeTimeLog < ActiveRecord::Base
#validations
validates :date, presence: true
validates :description, presence: true
#associations
belongs_to :employee
belongs_to :account
belongs_to :company_project
end
答案 0 :(得分:0)
您正在谈论此处的特权升级案例。
Rails Security Guide有一些提示:
对于某些Web应用程序来说,这是正常的,但如果用户无权查看所有项目,则肯定不会。如果用户将id更改为42,并且不允许他们查看该信息,则无论如何他们都可以访问它。相反,也要查询用户的访问权限:
@project = @ current_user.projects.find(params [:id])
在您的情况下,您希望允许:
@log = @employee.time_logs.build(project_id: 'good', …)
并且不允许这样:
@log = @employee.time_logs.build(project_id: 'bad', …)
查询属于某个帐户的所有项目,如下所示:
current_account.projects
可用于进一步查询:
current_account.projects.find('good')
#=> returns a record because ID belongs to account
current_account.projects.find('bad')
#=> raises ActiveRecord::RecordNotFound
这样您就可以确保将正确的project_id传递给您的控制器了!
user_supplied_project_id = params[:project_id]
timelog_params = params.merge(project_id: current_account.projects.find(user_supplied_project_id))
@log = @employee.time_logs.build(timelog_params)
答案 1 :(得分:0)
感谢所有帮助。这是最终的解决方案
user_supplied_project_id = params[:employee_time_log][:company_project_id]
timelog_params = user_supplied_project_id == '' ? params[:employee_time_log].merge(company_project_id: '') : params[:employee_time_log].merge(company_project_id: current_account.company_projects.find(user_supplied_project_id).id)