2014-09-04 1 views
3

ActiveRecord scope과 같은 관계를 수정하는 방법은 무엇입니까?범위에서 관계를 업데이트 하시겠습니까?

는 특히, 나는이 작업을 수행 할 수 있도록하려면 : fake_destroy_all 내가 만들려고 해요 기능이

Model.some_scope.fake_destroy_all 

. .update_all(deleted: true)과 거의 같습니다.

def fake_destroy_all(relation = Model) 
    relation.update_all(deleted: true) 
end 

#... 

Model.fake_destroy_all(Model.some_scope) 

을하지만 그 이상이 아니다 :

약한 대안이 될 것입니다. 내가하고 싶은 것은 다음과 같습니다 :

scope :fake_destroy_all, update_all(deleted: true) 

그러나 그것은 작동하지 않습니다.

제가 설명하는 것과 비슷한 것을 할 수 있습니까?

def self.fake_destroy_all 
    self.update_all(deleted: true) 
end 

그것은 관계의 모든 클래스 메소드를 유지하는 것이 밝혀 :

+2

다음 페이지를 참조하십시오. http://stackoverflow.com/questions/23017070/how-to-hide-records-rather-than-delete-them-soft-delete-from-scratch/23017174#23017174 – MrYoshiji

답변

3

이 시도해보십시오. 범위는 클래스 메서드이기도하며 범위를 "연결"할 수있는 정확한 메커니즘입니다.

따라서이 모델과의 관계에는 self이 관계의 인스턴스 인이 방법이 있습니다.

범위 구문은 아마도과 같이 해결할 수 있습니다 (지금 테스트, 대신 간단한 메서드 호출의 람다주의 수) :이 효과적으로 호출 람다 내부 업데이트하지 않고

scope :fake_destroy_all, -> { update_all(deleted: true) } 

나는 가정, 을 이 메소드는 클래스 정의로 scope를 호출 할 때 where에는 부작용이 없으므로 where 유형 범위에서 작동합니다., 해당 필터 만 반환합니다. 그것은 한 번 평가되고 현재 사용중인 방법으로 저장됩니다.

그러나 람다을 사용하면 실행은 정의 될 때까지 범위가 실제로 적용될 때까지 유지됩니다. update_all에는 의 부작용이 있으므로이 필요합니다.

끊임없이 변화하는 조건의 범위를 지정하는 경우 동일한 속임수가 유용합니다. 가장 단순한 경우는 Time.now에 대한 종속이며 시간이 지남에 따라 변경되며 매번 다시 평가해야합니다.

그러나 클래스 방법을 사용하는 것이 좋습니다. 범위는 필터와 비슷하지만 "필터 적용"과 비슷합니다. 이 방법도 효과가있을 수 있지만 범위는 용도에 따라 의미가 있습니다.

관련 문제