2011-09-01 1 views
7

나는 워드 프로세서에서이자동으로 예외를 발생시키는 대신 before_add 연관 콜백을 사용하여 건너 뛰기 하시겠습니까?

has_many :roles, :before_add => :enforce_unique 

def enforce_unique(assoc) 
    false if exists? assoc 
end 

을 할 노력하고있어 : "는 before_add 콜백 예외가 발생하면 개체가 컬렉션에 추가되지 않습니다." 다음은 추가를 방지하지 않는 거짓 위의 사용, 그래서 나는이 작업을 수행하도록 강요하고 있습니다 :

def enforce_unique(assoc) 
    raise if exists? assoc 
end 

이 방법, 그것은 추가되지 않는 것은 사실이지만, 그것은 또한 처리 할 수있는 예외를 발생 . 별로 유용하지 않아요. FALSE를 반환하면 저장 (또는 추가)을 방지하지만 예외를 발생시키지 않는 일반 AR 콜백 before_save와 같이 동작하는 것이 더 좋을 것입니다.

위의 경우 위의 경우 자동으로 assoc을 추가하지 않는 것이 좋습니다. 이것을 할 수있는 방법이 있습니까? 나는 무엇인가 놓친다? 아니면 여기서 유일한 예외를 제기하고 있습니까?

답변

1

협회는 다형성하지 않으면 당신은 같은 것을 할 수있다 :이 질문은 조금 오래된

1

와 관련있는 것을 우리에게 name_of_model 역할의 내부

validates_uniqueness_of :name_of_model 

을,하지만 난 가로 질러왔다 최근에 같은 문제가 있습니다. 여기에 내가 그것을 해결하는 방법입니다

def enforce_unique |obj, x| 
    v = obj.roles 
    if i = v.index(x) 
    v.slice! i 
    end 
end 
2

방법은 내가 루비 흐름 제어 의미 throwcatch을 사용하는 것입니다 생각을 해결하기 위해. 예외적 인 상황이 아니기 때문에 예외 사항을 제기하는 것은 적합하지 않습니다.

나는 일을 결국 :

catch(:duplicate) do 
    association.create({}) 
end 

그리고를 다음 before_add 콜백에서, 내가 그랬어 :

if(Class.where({}).first) 
    throw :duplicate 
end 

던져에 더/여기 잡아 :

http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue-im-so-confused/

0

이후 이 질문은 그것이 포함되는 것을 막기보다는 저축에 관한 것입니다.

class Role < ActiveRecord::Base 
    belongs_to :user, inverse_of: :roles 

    def save 
    super unless self.new_record? && user.has_existing_role?(self) 
    end 
end 

(!) 참고을 : 내가 돈 '목록에서 D는 일시적는 관련 모델에 저장 재정의하는 시도하고 역할이 존재하는 경우 단지 그것을 저장할 수 없습니다 (그 모델을 제어에 관심이 없다 컨트롤러에 의해 예) 비즈니스 로직을 어딘가에 배치해야하므로 액티브 레코드 패턴과 함께 사용하면 마른 컨트롤러 인수를 구입하지 않아도됩니다. 액티브 레코드 (Ruby AR 보석을 특별히 언급하지 않음)와 같은 비즈니스 도메인 패턴이 좋지 않으면 (예 : 컨트롤러 레이어에서) 실제로 레이어를 필요로합니다.이를 달성하기위한 수단으로 서비스 객체 또는 데코레이터 패턴을 사용할 수 있습니다 .

또 다른 방법은 연관성을 위해 <<과 같은 업데이트 방법을 재정의하고 기존 역할과 일치하는 경우 자동으로 역할을 삭제하는 것입니다. 연결 메소드 재정의 세부 사항은 ActiveRecord Association Class Methods Documentation

입니다.