2014-12-08 54 views
1

我有一个Company,UserDepartment模型。有多个不同的公司,其中每个部门都有has_many在has_many属性上的轨道验证

A User可以属于多个Departments通过UserDepartments连接表。

在我的形式为User,我使用:

<%= f.collection_check_boxes :department_ids, @user.company.departments.all, :id, :name %> 

什么是验证恶意用户没有使用卷曲等发布不属于用户的公司部门标识的最佳实践?

我目前在连接表本身上使用以下内容,但是想知道是否有更好的接受练习?作为一个单独的说明,如果用户确实提交了一个恶意标识,那么rails会显示一个异常页面,而不是通常的带有errors对象的表单呈现页面;这是为什么?

不雅之处的另一个小点是,当您提交用户表单并说5个不同部门选中时,此验证将创建5个SQL查询。据推测,如果用户模型本身进行了验证,则可以使用一个查询来完成。当然,数据完整性是我最关心的问题。

谢谢。

+0

在连接表模型中添加验证可能不是一个好主意。你能发布部门模型和用户模型的代码吗? – kasperite 2014-12-08 01:33:33

+0

@kasperite这只是一个例子:部门只是'belongs_to:company'和User'belongs_to:company'和'has_many:user_departments','has_many:departments,through::user_departments'。 – 2014-12-08 02:04:59

回答

0

阻止恶意用户蜷缩到服务器的事情是csrf_token,所以Rails正在帮你处理这个问题。这可能是你看到的错误。

我会保持业务逻辑验证正在验证的事情。连接表不是Thing本身;事实上,它没有东西。

所以通过将验证移动到用户,您可以将逻辑保存在一个位置并避免额外的sql。

def ensure_departments_in_company 
    company_department_ids = company.departments.pluck(:id) 
    unless deparment_ids.map { |id| id.in?(company_department_ids) }.all? 
    errors.add(:user, "This department does not match the user's company.") 
    end 
end 
+0

谢谢,卷曲的例子确实不正确。但是,如果我去例如“检查元素” Safari在其中一个复选框上,并将值更改为不同的数字,然后没有验证Rails会将用户的部门设置为不属于该用户公司的部门。 我测试了你的代码,它的工作原理,谢谢。不过,我将错误添加到':departments'符号。 – 2014-12-08 02:16:03