3

Alex Reisnerのブログ投稿からのヒントを使用して、モデルの1つにSTIを実装しました。私はすでにすべてのサブクラスにスーパークラスのコントローラーを使用させ、追加の属性を保持するためにシリアル化/保存しました。model_nameスーパークラスにメソッドとself.select_optionsメソッドを追加し、 Alexのブログからプリロード初期化子を追加しました。また、メソッドcollection_selectを使用するように_formビューヘルパーと属性の検証を変更しましたself.select_options。私のサブクラスはすべて、app / models / subfolder内の個々のファイルにありますが、SubFolder::Subclassのように名前空間は付けられていません。

それから私は問題にぶつかり始めます。コードを変更するself.select_optionsと、すべてのサブクラスの戻りを停止します。小さなサブセットのみを返すか、何も返しません。したがって、検証と_formの関連付けにより、コードの変更後にモデルを編集/更新することはできません。私の知る限り、コードを変更すると、Railsは環境をリロードしますが、サブフォルダー内のモデルはリロードしません。

多くの提案のようにconfig.autoload_pathsにルートを追加しようとしましたが、最終的には機能しませんでした。

したがって、最終的には、次のことが必要です。

  • 自動読み込みを修正するために、変更のたびにサーバーを再起動する必要はありません。
  • 配列を手動で維持することを避けるために、すべての子を含むサブディレクトリに基づいてください
  • Rails 3.2.11、ruby 1.9.3p125、ubuntu 12.04.01、rvm
4

2 に答える 2

3

私はこの回答とこの回答のコードを組み合わせて、下部にあるすばらしいブログ投稿から収集した知識を組み合わせることにしました。はconfig.autoload_paths何の助けにもならないようでしたが、私は彼らをそこに留めました。重要な部分は、起動時とリロードのたびにサブディレクトリ内のすべてのファイルを必要とするイニシャライザです。試しloadてみましたがrequire_dependency、うまくいきませんでした。いつもリロードする必要がないのは間違いなく良かったです。

application.rbで

config.autoload_paths += %W(#{config.root}/app/models/configuration)

development.rbで

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

preload_sti_models.rb内

if Rails.env.development?
  Dir.entries("#{Rails.root}/app/models/subfolder").each do |c|
    require_dependency File.join("app","models", "subfolder", "#{c}") if c =~ /.rb$/
  end
  ActionDispatch::Reloader.to_prepare do
    Dir.entries("#{Rails.root}/app/models/subfolder").each do |c|
      require_dependency File.join("app","models", "subfolder", "#{c}") if c =~ /.rb$/
    end
  end
end

有用な情報を含むいくつかのブログ投稿

  1. http://wondible.com/2012/01/13/rails-3-2-autoloading-in-theory/
  2. http://wondible.com/2011/12/30/rails-autoloading-cleaning-up-the-mess/
  3. http://wondible.com/2011/12/23/give-rails-autoloading-a-boot-to-the-head/
  4. http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

編集:それは既知のものです。

于 2013-02-05T15:54:24.363 に答える
1

このソリューションは、上記のundefinedvariableに似ていますが、もう少しDRYです。

# organize your sti classes in directories named after the parent
sti_directory_paths = [
  Rails.root.join("app","models","subfolder_one"),
  Rails.root.join("app","models","subfolder_two"),
]

def require_sti_model(path, filename)
  require_dependency (path + filename).to_s
end

# if you use something like guard, just exclude from production
unless Rails.env.production?
  sti_directory_paths.each do |sti_directory_path|
    Dir[sti_directory_path + "*.rb"].each do |filename|
      require_sti_model(sti_directory_path, filename)
      ActionDispatch::Reloader.to_prepare do
        require_sti_model(sti_directory_path, filename)
      end
    end
  end
end
于 2013-08-11T16:37:38.327 に答える