Rails模型验证

时间:2014-06-14 20:15:37

标签: ruby-on-rails

如何在以下方案中验证模型。我们有三种模式,即帐户,时间日志和项目。帐户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

2 个答案:

答案 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)