2009-10-15 2 views
3

나는 하나의 테이블 상속을 통해 34 가지 유형의 사용자가있는 대규모 Rails 앱을 보유하고 있습니다. 앱이 처음 디자인되었을 때, 사용자는 유형에 따라 다른 행동을 취할 것으로 추정되었습니다. 이 가정은 틀렸으므로 리팩토링을 고려하고 있습니다.다른 유형의 사용자를 처리하는 가장 좋은 방법은 무엇입니까?

질문은 어떻게 사용자 STI를 리팩터링합니까?

  • 사용자에 부울 속성 톤 (예. User#is_employee?, User.is_contractor?)
  • User#user_type-User#type 이름을 바꾸고 바로 필드
  • 일부 끔찍한 조회 테이블 솔루션
  • 뭔가 내가에 따라 문자열 매칭을 추가 '누락되었습니다 ...

사용자가 ACL을 이유로'유형 '이 필요하지만 STI를 사용하면 실제로는 그냥 빈 모델입니다. STI는 specing, 일반적인 엉덩이 통증 등의 문제를 일으 킵니다.

답변

0

34 모델 모두 비 었습니까?

그들은 당신이 할 수있는 경우 :

self.inheritance_column = nil 

귀하의 사용자 모델의 상단에, 당신은 단지 유형을 확인 할 수있는 방법을 :

if @user.type == "Employee" 
    # do something 
end 
+0

흥미롭고 간단한 ... –

0

이 글은 모르고 질문에 대답하기 힘든 당신의 'ACL 이유'가 그 타입을 어떻게 사용하는지는 ...

나는 항상 User#user_type과 함께갔습니다. 이 사건은 아주 희귀해서 항상 좋았다. 비록 내가 몇 가지 사용자 유형을 가지고있다.

def method_missing(method, *args, &block) 
if(method.to_s.starts_with?('is_')) 
    self.user_type == method.to_s.gsub("is_", "").gsub("?", "") 
end 
end 

: 또 다른 옵션 (당신이 당신의 두 번째 옵션을 암시하고 있었는지 수) 문자열 일치를 처리 할 수 ​​method_missing를 사용하고 옵션 예를 들어 1

처럼 행동 할 수 있도록하는 것입니다 user_type이 계약자 인 경우 is_contractor?에 대해 true를 반환합니다.

제공된 스 니펫이 테스트되지 않았으며 연결된 gsub가 꽤 끔찍한 것으로 보입니다. 나는 이것이 멋진 작은 정규 표현식이나 다른 영리한 방법으로 쓰여질 수있을 것이라고 확신한다.

3

정말 필요한 것은 사용자 유형이 아닌 역할입니다. 나는 많은 사용자 유형으로 끝날 때 이것이 보통 경우 인 것을 발견했다, 어떤 사용자는 하나 이상의 역할을 가지고 있기 때문이다.

간단한 ACL 모델은 다음과 같습니다. 사용자는 많은 역할을 가지며 각 역할에는 많은 권한이 있습니다. 사용자에 대한 사용 권한 집합은 사용자가 속한 모든 역할에 대한 모든 사용 권한 집합입니다.

좀 더 복잡한 경우 권한은 대상 및 시간 기반 (!)의 몇 가지 이유 때문에 데이터베이스의 행보다는 계산 된 속성이되는 경우가 많습니다.당신이 얻을 필요로

@user.can_view_payroll_info_for?(@employee, 2.years.ago) ==> true 
@user.can_view_payroll_info_for?(@employee, Time.now) ==> false 

하지만 대부분의 경우, 역할은 높은 해상도 :

@john.has_role(:content_author) ==> true 
@john.has_role(:moderator) ==> true 

@benny.has_role(:content_author) ==> true 
@benny.has_role(:moderator) ==> false 

@michael.has_role(:moderator) ==> true 
@michael.has_role(:content_author) ==> false 

을 당신은 단순히 그것을 구현할 수있는 쉼표로 구분 된 (검증) 문자열의 역할 '열로 역할을 정규화하려면 사용자 또는 조인 테이블에 대해.

관련 문제