2012-04-04 8 views
4

레일 스 캐 폴딩을 사용하여 네임 스페이스 모델을 만들면 두 개의 파일이 생성됩니다. 예를 들어,이 비계 : 나는 레일이 직원 모듈을 언로드 개발 모드에서 문제로 실행하고레일 네임 스페이스 모델의 네임 스페이스 정보 손실

/app/models/staff.rb  
module Staff 
    def self.table_name_prefix 
    "staff_" 
    end 
    ... 

/app/models/staff/location.rb 
class Staff::Location < ActiveRecord::Base 
    ... 

하고 다시로드하지 :

rails generate model Staff::Location name:string address:string 

이러한 파일을 생성합니다. 이로 인해 위치와 같은 몇 가지 귀찮은 버그가 table_name_prefix 누락으로 인해 테이블에 액세스 할 수 없습니다. 다형성 관계를 통해 직접 모델에 액세스하지 않으면 문제가 커질 수 있습니다.

모듈을 일관성있게로드 할 수없는 것 같습니다. 이름 공간 모델을 수행하는 가장 좋은 방법입니까? 그렇다면 무엇을 놓치고 있습니까?

+0

이 오류를 생성하는 일부 코드의 예를 들려 줄 수 있습니까? 어쩌면 자주 실패하는 관계 중 하나일까요? – Brandan

답변

2

약 1 년 후, 나는이 질문에 대한 답을 찾았습니다. 이 답변은 특히 레일 3.1에 대한 것입니다. 레일 3.2의 문제인지 잘 모르겠습니다.

모델을 설정할 때 문제가 발생합니다. 스캐 폴딩을 사용하면 도우미 파일이 생성되지 않습니다. 일반적으로 /app/helpers/staff/location_helper.rb에 있습니다. 이 파일을 설정하는 데는 두 가지 방법이 있습니다.

module Staff::LocationHelper 
    ... 
end 

module Staff 
    module LocationHelper 
    ... 
    end 
end 

특히 헬퍼 용으로는 첫 번째 해결 방법을 사용해야합니다. 레일스 프로젝트의 다른 부분에서 네임 스페이스를 사용하는 다른 모듈에이 모듈을 사용할 필요가 없습니다. 실제로 루비의 일부 구조에는 두 번째 해결 방법이 필요합니다.

헬퍼를 선언 할 때 두 번째 솔루션을 사용하면 헬퍼 파일의 스태프 모듈이 /app/models/staff.rb의 모듈보다 우선 적용되는 경우가 있습니다. 파일의 빈 스태프 모듈로 자동 교체합니다. 도우미가 항상로드되지 않기 때문에 100 %의 시간은 발생하지 않습니다.

2

레일즈 3.2.2에서 문제를 재현 할 수 없었지만 이전과 같이 실행했습니다. 개발 모드에서이 문제를 해킹하는 일반적인 방법은 ActionDispatch 콜백을 사용하는 것입니다. config/environments/development.rb이 추가 : 그 블록에서 할

MyApp::Application.configure do 
    ActionDispatch::Callbacks.before do 
    load Rails.root.join('app', 'models', 'staff.rb') 
    end 
end 

아무것도 그렇게 만 개발 모드에서 그 일을하고 있는지 확인, 각 요청하기 전에 실행됩니다 † 그렇지 않으면, 당신이 고통을 것입니다. 프로덕션 환경에서 성능이 저하되었습니다.

staff.rb 파일과 Staff 모듈 자체에 메시지를 기록했으며 두 메시지가 각 요청에 대해 로그에 기록되었습니다. 나는 그 the documented way to execute code before each request only when cache_classes is false 것으로 보인다 때문에, to_prepare 콜백을 사용하여 시도 †


. 하지만 그것은 응용 프로그램을 다시 시작한 후에 만 ​​실행되는 것처럼 보였습니다. 그는 적어도 내가 사용한 것보다 약간 다른 구문을 사용하고 있지만 적어도 one other open Stack Overflow question regarding this이 있습니다. to_prepare을 사용할 수 있다면 before 대신 제안 할 것입니다.

관련 문제