2012-11-24 4 views
3

을 저장 모델에 업데이트되지 SQL 로그는 같은 뒤에 INSERT가있을 것입니다 :counter_cache 후 나는 MySQL은 나를 위해 회계 장부의 일부를 할 수 있도록하기 위해 <code>counter_cache</code>을 사용하고

UPDATE `containers` SET `items_count` = COALESCE(`items_count`, 0) + 1 
    WHERE `containers`.`id` = 57 

인 내가 전 그것을하기 위하여 pected. 그러나 container[:items_count]은 오래되었습니다.

... 업데이트 된 값을 가져 오지 못하면 container.reload입니다. 내 마음에 일종의 패배의 일환 : 사용자 정의 내장 된에 찬성하여 counter_cache를 사용하는 목적의 일부를 패배 시키십시오. 특히 reload이 실제로는 items_count 속성에 액세스하려고하기 때문에 원하지 않을 수 있습니다. (내 모델은 꽤 코드 무거운 때문에 도메인 로직의 성격, 그래서 때로는 하나의 컨트롤러 호출로 여러 가지를 저장하고 생성해야합니다.)

나는 콜백 자신을 땜질 할 수 이해하지만이 날 것으로 보인다 간단한 기능에 대한 기본적인 기대. 다시 말하지만, 코드가 제대로 작동하도록 추가 코드를 작성해야한다면 맞춤 카운터를 구현하는 것이 더 쉬울 수도 있습니다.

내가 뭘하고/틀릴 것이라고 생각하니?

답변

1

실제로 컨테이너에 항목을 알리지 않았지만 container.reload 할 때 실제로하는 일입니다. 그것. 시도해 보셨습니까?

container = Container.find(57) 
item = container.items.create() 

이렇게하면 항목이 컨테이너 컨텍스트에서 만들어지고 해당 연결이 만들어집니다.

+0

그거야. 나는 그것이 일방적으로 작동하고 다른 것은 작동하지 않는다는 것을 일관성있게 찾는다. – sehnsucht

+0

제게 이것은 작동하지 않습니다! 재로드 카운터가 업데이트 된 후에 만 나는 다양한 스타일'create','create!','build.save! '를 시도했습니다. – pablo

3

Container 인스턴스에서 항목 카운터의 값이 자동으로 업데이트 될 것으로 예상해서는 안됩니다. 대부분의 Rails 애플리케이션은 다중 프로세스 (및 종종 여러 서버) 구성에서 작동한다는 점을 명심하십시오. 한 프로세스가 다른 프로세스의 Container 인스턴스와 연결된 Item을 추가하면 카운터의 값이 부실 해집니다.

+1

데이터를 일관성있는 상태로 유지해야하는 부담이 모델에 있습니다. 그렇기 때문에 정체가 보증 할만 큼 높은 경우 서로 다른 격리 수준 및 낙관적 동시성 (optimistic concurrency)의 거래가 있습니다. 다른 사람이 다른 곳에서 데이터를 변경할 수있는 것은 counter_cache에만 적용되는 것이 아니라 보편적 인 문제입니다. 두 번째 테이블이 연속적으로 업데이트되는 경우 연속 된 두 개의 SELECT가 일치하지 않는 데이터를 생성 할 수 있습니다. 이와 관련하여 다른 누군가가 내 컨테이너에 Item을 추가하여 생성 한 경쟁 조건이 컨테이너에 액세스하기 전에'container.items'를 변경하는 것과 다른 이유는 알 수 없습니다. – sehnsucht