레일 : 환경에서 필요한 LIB 파일에 정의 된 필터 .RB는 생산 환경에서 Filter_Chain에서 사라집니다. 왜요?

StackOverflow https://stackoverflow.com/questions/620146

문제

Rails 응용 프로그램에는 Lib에 파일이 있는데, 무엇보다도 모든 컨트롤러에서 실행되는 필터를 설정합니다.

개발 환경에서 실행될 때는 모든 것이 잘 실행됩니다. 그러나 생산 중에는 필터가 누락됩니다. 재미있는 것은, 검사하는 것입니다 filter_chain, 나는 다른 필터가 남아 있음을 알았습니다. 플러그인 또는 나중에 특정 컨트롤러 클래스에 정의 된 것.

레일 엣지와 v2.3.0으로 이것을 테스트했습니다.

테스트 업데이트 :

나는 이제 오래된 레일로 테스트 한 후 v2.1.0으로 다시 존재하는 문제를 발견했지만 v2.0.5에 있지 않은 것으로 밝혀졌다. 986AEC5 철도는 유죄가되기로 약속합니다.


동작을 다음과 같은 작은 테스트 사례로 격리했습니다.

# app/controllers/foo_controller.rb
class FooController < ApplicationController
  def index
    render :text => 'not filtered'
  end
end

# lib/foobar.rb
ActionController::Base.class_eval do
  before_filter :foobar
  def foobar
    render :text => 'hi from foobar filter'
  end
end

# config/environment.rb (at end of file)
require 'foobar'

다음은 아래에서 실행할 때 얻는 출력입니다. 개발 환경:

$ script/server &
$ curl localhost:3000/foo
> hi from foobar filter

그리고 여기에 출력이 있습니다 생산 환경:

$ script/server -e production &
$ curl localhost:3000/foo             
> not filtered

이전에 언급했듯이 플러그인을 통해 동일한 작업을 수행 할 때 모든 환경에서 잘 작동합니다. 내가 필요한 것은 아래에있는 것을 넣는 것입니다 lib/foobar.rb 플러그인에서 init.rb 파일.

그래서 나는 이미 해결 방법을 가지고 있지만 생산 중에 무슨 일이 일어나고 있는지, 필터가 누락되는 원인을 이해하고 싶습니다.

나는 그것이 레일이 다른 환경에서 로딩을 처리하는 다른 방식으로 무언가라고 추측하지만 더 깊이 파어야합니다.

업데이트

실제로, 나는 이제 다음 구성 줄로 좁혔습니다.

config.cache_classes = false

만약 production.rb, config.cache_classes 변경되었습니다 true 에게 false, 테스트 응용 프로그램은 제대로 작동합니다.

나는 왜 클래스 리로드가 그런 일을 일으키고 있는지 궁금합니다.

도움이 되었습니까?

해결책

프레드릭 청 (Frederick Cheung) 레일 목록 가졌다 대답:

cache_classes는 단지 그 이상을 수행하기 때문입니다. 필터가 작동하기 전의 방식은 foo <bar이면 해당 지점의 막대에 정의 된 필터 만 Foo에 의해 상속됩니다. 나중에 막대에 추가하면 아무것도하지 않습니다.

개발 모드에서 앱이 시작되면 파일이 필요하고 Filter가 ActionController :: Base에 추가되었습니다. 나중에 첫 번째 요청이 나오고 컨트롤러가로드되고 해당 필터가 상속됩니다.

CACHE_CLASSES가 참되면 모든 응용 프로그램 클래스가 미리로드됩니다. 파일이 필요하기 전에 발생하므로 해당 파일이 실행될 때 이미 모든 컨트롤러가 존재하므로 영향을 미치지 않습니다. 이번 파일을 이니셜 라이저에서 요구 하여이 파일을 요구할 수 있지만 (앱 클래스가로드되기 전에 실행되는지 확인). 실제로 왜 이것을 application.rb에 넣지 않습니까?

프레드


나의 진짜 사례는 실제로 더 많은 관용이었고, 이것이 제가이 문제를 해결하는 방법입니다.

config.after_initialize do
  require 'foobar'
end

그만큼 after_initialize 프레임 워크가 초기화 된 후 블록 실행되지만 응용 프로그램 파일을로드하기 전에 영향을 미칩니다. ActionPack::Base 로드 된 후에는 응용 프로그램 컨트롤러가 있습니다.

나는 그것이 생산에서 진행되는 모든 예압을 다루는 일반적으로 안전한 방법이라고 생각합니다.

다른 팁

루비 스크립트를 떨어 뜨립니다

RAILS_ROOT CONFIG INITIALIZERS

그것은 포함되어 있습니다

require "foobar.rb"

이것은 나에게 prever_filter를 호출합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top