2014-12-08 4 views
1

나는 Company, UserDepartment 모델을 가지고 있습니다. 여러 개의 다른 회사가 있으며 각각은 has_many 부서입니다.레일 유효성 검사 has_many 속성

UserDepartments에서 UserDepartments의 조인 테이블에 속할 수 있습니다. User에 대한

내 양식에

가, 내가 사용

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

악의적 인 사용자가 사용자의 회사에 속하지 않는 department_id를 게시 할 말림 등을 사용하지 않은 것을 검증하기위한 가장 좋은 방법은 무엇입니까?

현재 조인 테이블 자체에서 다음을 사용하고 있습니다. 더 좋은 방법이 있는지 궁금합니다. 사용자가 악의적 ID를 제출 않는 경우 별도 참고로

class UserDepartment < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :department 

    validate :check_company_matches 

    private 
    def check_company_matches 
     unless user.company_id == department.company_id 
     errors.add(:user, "This department does not match the user's company.") 
     end 
    end 
end 

, 레일은 오류 개체 예외 페이지보다 일반적인 형태 렌더링 페이지를 나타낸다 그게 왜?

부적당하다는 또 다른 사소한 점은 5 개의 다른 부서가있는 사용자 양식을 제출할 때이 유효성 검사가 5 개의 SQL 쿼리를 생성한다는 것입니다. 아마도 User 모델 자체가 유효성 검사를 수행하면 하나의 쿼리로이 작업을 수행 할 수 있습니다. 당연히 데이터 무결성이 가장 중요합니다.

감사합니다.

+0

조인 테이블 모델에 유효성 검사를 추가하는 것은 좋지 않습니다. 부서 모델 및 사용자 모델의 코드를 게시 할 수 있습니까? – kasperite

+0

@kasperite 이것은 단지 예입니다. 부서는 단순히'belongs_to : company'이고 사용자는'belongs_to : company' 및'has_many : user_departments','has_many : departments, through : : user_departments'입니다. –

답변

0

악의적 인 사용자가 서버에 curl'ing하는 것을 막을 수있는 것은 csrf_token이므로 Rails가이 문제를 처리합니다. 아마 당신이보고있는 오류 일 겁니다.

유효성 검증과 같은 비즈니스 논리를 유효성 검사와 같이 유지할 것입니다. 조인 테이블은 자체가 아닙니다. 실제로, 그것은 전혀 없습니다.

그래서 유효성 검사를 사용자로 이동하면 논리를 한 곳에 보관하고 여분의 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

감사합니다. 컬 (curl) 예제가 실제로 잘못되었습니다. 그러나 예를 들어 '검사 요소'로 이동하면 Safari를 체크 박스 중 하나에서 선택하고 값을 다른 숫자로 변경하면 유효성 검사없이 Rails가 사용자 부서를 사용자 회사에 속하지 않는 부서로 설정합니다. 코드를 테스트 한 결과 작동합니다. 감사합니다. 나는 오류를': departments' 심볼에 추가했습니다. –