programing

하위 모듈을 만들지 않고 모델을 하위 폴더로 구조화하는 우아한 방법

nasanasas 2020. 12. 1. 08:08
반응형

하위 모듈을 만들지 않고 모델을 하위 폴더로 구조화하는 우아한 방법


내 앱 / 모델 폴더에 여러 모델이 있습니다. 이 폴더를 조금 정리하고 싶습니다. 서로에게 속한 모델을 하위 폴더로 이동합니다. 문제는 관례 상 모델 클래스가 해당 모듈로 네임 스페이스가 지정된다는 것입니다.

app / models / blog / post.rb
app / models / blog / comment.rb
app / models / user.rb

그래서:

app / models / blog / post.rb

class Post < ActiveRecord
end

그리고 아닙니다

class Blog::Post < ActiveRecord
end

다음은 Rails 3에서 사용한 것입니다.

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]

이 구성은 Rails가 모든 앱 / 모델 하위 폴더를 재귀 적으로 스캔하고 발견 된 모든 모델을로드하도록 지시합니다. 네임 스페이스가 필요하지 않습니다.


우리는 이것을해야했고 아주 간단한 방법이 있습니다.

모델을 하위 폴더로 이동 한 다음 rails에 environment.rb 파일의 모든 하위 폴더에서 파일을로드하도록 지시합니다.

config.load_paths += Dir["#{RAILS_ROOT}/app/models/*"].find_all { |f| File.stat(f).directory? }

네임 스페이스가 필요하지 않으며 앱에서 모델을 일반으로 참조 할 수 있습니다.


또한 하위 폴더를 만든 다음 application.rb 파일에 다음을 추가했습니다.

config.autoload_paths += Dir["#{config.root}/app/models/**/"]

그러나 모델과 동일한 이름을 사용하여 하위 폴더의 이름을 지정하는 경우이 작업만으로는 충분하지 않습니다 (예 : 여러 파일을 포함하는 'user'폴더 중 하나가 'user'). 이로 인해 포함 된 모델 (예 : '사용자 모델')과 다른 폴더 이름을 지정하여 해결할 수 있음을 발견 할 때까지 코드에 모든 종류의 오류가 발생했습니다. 실제로이 질문을 가리키는 http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/ 에서 제안을 찾았습니다 .


그래서 저는 Rails 2에서 다음과 같이 사용했습니다.

config.autoload_paths += Dir["#{config.root}/app/models/**/"]

그리고 다음 파일 :

  • app / models / user / base.rb : class User::Base
  • app / models / user / admin.rb : class User::Admin

Rails 3으로 업그레이드했을 때 다음 줄에 계속 오류가 발생 Expected .../app/models/user/foo.rb to define Foo했습니다.. Rails 2는 user / foo.rb에 넣은 것이 User::Foo단지 Foo.

그래서이 문제를 해결 한 방법은 모델 하위 디렉토리를 제거 autoload_paths하고 다음과 같이하는 것이 었습니다 .

다음과 같이 app / models / user.rb를 만들었습니다.

module User
  autoload :User, 'user/base'
  autoload :User, 'user/admin'
end

RailsEngines를 살펴볼 수 있습니다. 정확히 필요한 것은 아니지만 몇 가지 아이디어를 줄 수 있습니다.

그 외에는 스크립트가 잘 작동하는 것 같으면 (모델의 각 하위 폴더에있는 모든 파일을 읽고 필요할 수도 있음) 이에 대한 문제는 없습니다.


이 버전의 Tilendor 솔루션은 Rails 3에서 작동합니다.

config.load_paths 및 RAILS_ROOT는 Rails 3에서 더 이상 사용되지 않습니다. 또한 environment.rb가 아닌 config / application.rb의 config 블록에 넣어야합니다.

config.autoload_paths += Dir["#{Rails.root.to_s}/app/models/*"].find_all { |f| File.stat(f).directory? }

내 Rails 3.2.3 앱에서 일부 모델을 하위 디렉토리로 옮긴 후 다음과 같은 오류가 발생했습니다.

Expected /.../.../app/models/project/project_category.rb to define Project::ProjectCategory

연결 호출 용 (예 : Project.first.project_category).

결국 내가 찾은 해결 방법은 하위 디렉토리의 모델에 대한 모든 연결에 대해 : class_name을 설정하는 것입니다.

class Project < ActiveRecord::Base

  belongs_to :project_category, :class_name => "::ProjectCategory"

end

여기서 "::"부분은 'models / project'하위 디렉토리에 정의되어 있음에도 불구하고 ProjectCategory 모델에 네임 스페이스가없는 Rails를 가리 킵니다.


이것은 Rails 5에서 나를 위해 일했습니다.

다음에 추가 application.rb

config.autoload_paths += Dir[ Rails.root.join('app/models/**/') ]

폴더에 모델과 동일한 이름을 가질 수는 없습니다.


더 나은 솔루션을 찾을 때까지 app / models 폴더에 init.rb를 만들었습니다.

app / models / init.rb

%w[blog].each do |folder|
  path = [File.dirname(__FILE__), folder, "*.rb"].join('/')
  Dir[path].each {|file| require file }  
end

지금까지 서버의 목적.


All the above answers didn't work for me. Somehow 'models' folder was loaded with subfolders, which resulted in 'Expected to contain ::.

Most of my subdirs were STI classes so I've moved them to app/models_sti//*. Then all I needed to do was to put in application.rb

#config.autoload_paths += Dir["#{Rails.root.to_s}/app/models/**/"]
# Loaded dynamically (cache_classes == false ?)
config.autoload_paths << Rails.root.join('app', 'models').to_s
config.autoload_paths += Dir["#{Rails.root.to_s}/app/models_sti/*"].find_all { |f| File.stat(f).directory? }

# Eager_load_paths - used only when cache_classes == true [rails spec says so]
config.eager_load_paths.delete_if do |path|
  # If I didn't delete it from eager_load_paths I got errors even in develop
  path == Rails.root.join('app', 'models_sti').to_s
end
config.eager_load_paths += config.autoload_paths

참고URL : https://stackoverflow.com/questions/1445341/elegant-way-to-structure-models-into-subfolders-without-creating-submodules

반응형