2009-07-22 5 views
14

컨트롤러에 변수를 저장하고 싶습니다. 하나의 액션으로 초기화하고, 다른 액션에서 그것을 증가시키고, 또 다른 액션에서 그것을 읽고 싶습니다. @foo으로이 변수를 선언하는 것은 @foo이 생성 된 작업이 종료 된 후에 종료되기 때문에 작동하지 않습니다.
이 변수가 모델에 저장되는 것을 원하지 않습니다.컨트롤러의 여러 액션에 인스턴스 변수를 저장하려면 어떻게해야합니까?

이 변수를 세션에 저장하는 것 외에도 보존 할 수 있습니까?
나는이 간단한 문제를 몇 번 겪어 본 것처럼 보이며, 해결 방법에 대해 알고 싶습니다.

답변

22

아니요. 컨트롤러 액션에 대한 각 호출은 상태 비 저장입니다. 컨트롤러 동작이 완료된 후에는 아무 것도 사용할 수 없습니다. 새 컨트롤러 인스턴스가 각 요청에 대해 생성 된 다음 요청이 끝날 때 삭제됩니다.

세션 또는 데이터베이스 모델에 저장하지 않으려는 경우 해당 변수를 특정 세션에만 적용하려는 경우 많은 옵션이 없습니다.

모든 세션에서 전역 인 경우 @instance_variable이 아닌 @@class_variable으로 입력 할 수 있지만 여러 개의 Rails 프로세스 (각각 자체 사본이 있음)가 시작되면 지저분해질 수 있습니다. 당신은 threadsafe 모드에서 실행 중입니다, 당신은 불쾌한 동시성 버그로 끝날 수 있습니다.

난 당신이 memcached와 같은 것을 볼 수도 있겠죠,하지만 당신은 여전히 ​​(그것이 글로벌 않는 한) 일부 USER_ID 또는 다른 세션 마커

7

당신은 Rails.cache 내장의 사용을 만들 수있는 그 키에 필요한 것 메커니즘을 사용하여 값을 저장하지만 첫 번째 응답에서 언급 한 것처럼 user_id와 같은 값을 입력해야합니다. 이것은 다른 저장 메커니즘으로 백업 할 수 있기 때문에 갈 수있는 좋은 방법입니다. 당신이 볼 수 있었다

Rails.cache.write(:foo) 
# in later action 
Rails.cache.read(:foo) 

또 한가지는 한 후속 요청보다 마지막으로 더 플래시 값을 만들 수있는 킵 방법을 제공 플래시 해시입니다.

flash[:foo] = some_value 
flash.keep(:foo) 

행동이 당신이 액세스 할 수 있습니다, 당신은 더 이후의 행동에 살아 남기하려는 경우 다시 계속 전화 :

그래서 행동 하나에 당신이 값을 만들 수 있습니다.

flash[:foo] #use it for something 
flash.keep(:foo) # keep it for another request 

http 요청의 컨텍스트 내에서 제대로 수행하는 것은 까다로운 작업입니다.

+0

캐시는 좋은 생각이지만 여러 웹 서버가있는 경우 플래시 방법이 작동하지 않을 것이라고 생각합니다. – Scott

+0

플래시 해시가 실제로 세션에 저장되어 있기 때문에 세션 저장 공간에 따라 달라집니다. 예를 들어 세션이 비활성화 된 경우에만 flash.now가 작동합니다. – paulthenerd

+0

캐시가 정상입니다. 그러나 MemoryStore를 사용하는 경우 프로세스 당 메모리이므로 모든 요청을 처리하는 단일 프로세스가 없으면 후속 요청이 메모리에있는 프로세스를 치지 못할 수 있습니다. 메모리 저장소가 memcached에 의해 뒷받침된다면 훨씬 좋을 것입니다. –

1

단순한 카운트 또는 문자열 인 경우 가장 좋은 해결책은 세션에 저장하는 것입니다. 그렇게하면 여러 웹 서버를 사용할 수 있습니다.

왜 세션을 사용하지 않습니까?

+0

저는 Rails에 처음 접했을뿐입니다. 그리고 저는 세션이 사용자 ID와 같은 * 중요 사항 *에 해당한다고 생각했습니다. 카운터처럼 사소한 것이 아닙니다. 감사. –

11

나는 세션을 사용하지 않는 이유에 대해 궁금해하십니까? 자신의 액션에서 세션으로 직접 작업하는 것을 좋아하지 않는다면 필터가있는 살아있는 @foo 인스턴스 변수를 에뮬레이션 할 수 있습니다. 아마도이게 뭔가?

class FooController < ApplicationController 
    before_filter :load_foo 
    after_filter :save_foo 

    private 
    def load_foo 
     @foo = session[:foo] || 0 
    end 

    def save_foo 
     session[:foo] = @foo 
    end 

end 

당신의 행동을하여 @count 인스턴스 변수를 통해 값을 조작 할 수 있으며이 자동으로 세션 지속됩니다.

1

세션이 물지 않기 때문에 걱정하지 마십시오.

또한 세션이이 작업을 수행하는 가장 좋은 방법 일 수 있습니다.

관련 문제