2014-12-15 2 views
4

Compact (::) 구문 대신 Rails 앱에서 일관되게 중첩 모듈/클래스 정의를 사용하려고합니다. 그러나 항상 모듈 파일 자체를로드하는 것은 아니며 여기에는 table_name_prefix이 포함되어 있습니다. 루비 2.1.1에 레일 4.1.8를 사용Rails의 중첩 된 모듈 table_name_prefix

...

rails new my_app 
... 
rails g scaffold User 
rails g scaffold Blog::Post 

app/models/blog.rb 작성

module Blog 
    def self.table_name_prefix 
    'blog_' 
    end 
end 

자동 로딩 blog.rb에서 실수 방지 레일의 많은 방법이있을 것 . 가장 간단한 예는 도우미를 통한 것입니다.

에서 변경 app/helpers/blog/posts_helper.rb :

module Blog::PostsHelper 
end 

에 :

module Blog 
    module PostsHelper 
    end 
end 

실행 서버, /users를 방문하고 /blog/posts를 방문하십시오

SQLite3::SQLException: no such table: posts: SELECT "posts".* FROM "posts" 

비슷한 문제가 다른 곳에서 발생할 수 등 모델 테스트에서. 그것은 도우미에 국한되지 않습니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 명시 적으로 blog.rb 및 다른 네임 스페이스 모듈을로드합니까? 자동 로딩에 의존하지 않는

+0

문제를 재현 할 수 있습니다. - 감사합니다. Anthony. github에서 문제를 만들고 팀이 말하는 것을 확인합니다. – Anthony

+0

아마도 ... 나는 레일스에 대한 변경을 제안하기보다는'blog.rb'가로드되도록하는 최선의 방법을 찾고 있습니다. 그것은 분명히 많은 사람들이 겪은 문제는 아닙니다 ... –

답변

0

하나의 솔루션으로, 대신 ActiveRecord::Base에서 직접 다음에서 상속 모델을 설정하는 것입니다 :

class CustomActiveRecordBase < ActiveRecord::Base 
    self.abstract_class = true 

    # If no table name prefix has been defined, include the namespace/module as 
    # table name prefix, e.g., Blog:: -> blog_ 
    def self.table_name 
    # If a table_name_prefix has been defined, follow default behaviour 
    return super if full_table_name_prefix.present? 

    # Find the prefix, e.g., Blog::Post -> 'blog', User -> '' 
    prefix = model_name.name.deconstantize.underscore 

    # If no prefix, follow default behaviour 
    return super unless prefix.present? 

    # Otherwise add the prefix with an underscore 
    "#{prefix}_#{super}" 
    end 
end 

그런 다음 blog.rbself.table_name_prefix을 정의 할 필요가 없습니다.

the default active record templates을 기준으로 및 module.rb의 적절한 파일을 통해 향후 모델의 기본값으로 설정할 수 있습니다.

모두 원숭이 패치 ActiveRecord::Base을 수행 할 수 있지만,이 테이블 접두사가없는 등 ActiveRecord::SchemaMigration 같은 다른 클래스, 방해한다.

관련 문제