2014-12-08 52 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