2017-01-05 3 views
4

appディレクトリでは、サブディレクトリのいくつかに名前空間を持つクラスと、トップレベルクラスを含むサブディレクトリが必要です。たとえば、次のように`app`ディレクトリ内の名前空間

config.paths = Rails::Paths::Root.new(Rails.root) 
config.paths.add 'app/models', eager_load: true 
config.paths.add 'app', eager_load: true 

  • app/models/user.rb::User
  • app/operations/foo.rb::Operations::Foo
  • app/operations/user/foo.rb当社application.rbには、次の設定が含まれてい::Operations::User::Foo

を定義を定義を定義します210

これはほとんどの場合うまく動作しますが、開発モードでRailsのオートロードがオンになっていると、間違ったクラスが読み込まれることがあります。例えば、::UserOperations::Userと間違えられ、逆も同様です。

エラーが発生しないようにこの動作を構成する方法はありますか?

私が考えることができる唯一の回避策は、とapp_namespacedの行に沿って、 "namespaced"クラスの2番目のディレクトリを作成することです。アプリレベルのコードはapp内にある必要があります。app/namespacedしかし、これらは私にとって醜い回避策のように思えます。

編集:少し例@dgilperezによりを求めて:

# app/models/user.rb 
class User 
end 

# app/models/group.rb 
class Group 
    def some_method 
    # Since we're in a top-level namespace, User should always 
    # resolve to ::User. But, depending on some seemingly random 
    # factors, it sometimes resolves to Operations::User. 
    User.new 
    end 
end 

# app/operations.rb 
module Operations 
end 

# app/operations/user/create.rb 
module Operations::User 
    class Create 
    def some_method 
     # Here, as expected, I need to prefix with "::" as 
     # 'User' would refer to the module we're currently in. 
     # That's fine and works. 
     ::User.new 
    end 
    end 
end 
+1

(http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#when-constants-aren-t-逃した) – Stefan

+0

クラスの定義を貼り付けることはできますか?混乱の原因となるコード(呼び出しと場所) – dgilperez

+0

この@dgilperezを見ていただきありがとうございます。ちょっとした例を追加しました。 – Remo

答えて

0

はい、これはRailsの自動ロードの欠点です。デフォルトでは、/appからすべてをロードしますが、ディレクトリ構造の第1レベルは名前の一部ではありません。 app/models/user.rbUserと定義できるので、Models::Userである必要はありません。

ロードパスを混乱させる必要はありません。いくつかのアプローチ/回避策がここにあります。

  1. 私の現在のプロジェクトでは、名前空間ディレクトリを2倍にしました。我々はServiceObjects::User::Importを定義したい場合は、私たちは、私が個人的に(app/customまたはあなたが望む何もすることができます)app/libにすべての「非標準」のものを置くことですそのアプローチのバリエーションを、好むapp/service_objects/service_objects/user/import.rb

  2. にそれを置くことを意味。この方法では、ディレクトリ名の奇妙な複製はなく、すべてのカスタムコードがうまく含まれています。

[定数が不在されていない場合]で説明したようにあなたは完全修飾定数や `require_dependency`を使用することができ