RailsでNameError uninitialized constant

1つのRails上に複数アプリを載せようと思って、アプリごとにサブディレクトリを切って格納していたところ、1対多の紐づけ設定のところでNameErrorが出てきて困った。アソシエーションでclass_nameを追記したら直った。

やりたいこと

1つはptという名前でアプリを作りたい。たとえばこんな感じ。
/app/controllers/pt/events_controller.rb
/app/controllers/pt/trainers_controller.rb
/app/models/pt/trainer.rb
/app/models/pt/event.rb

もう1つはnoteという名前でアプリを作りたい。
/app/controllers/note/books_controller.rb
/app/models/note/book.rb

Sacaffold

ディレクトリを切る場合は、「::」をつける。

$ rails g scaffold pt::trainer name:string birthdate:date sex:integer email:string title:string comment:text area:string
$ rails g scaffold pt::event name:string the_date:date title:string comment:text area:string pt_trainer:belongs_to

アソシエーション

ptアプリ(失敗例)

Pt::Trainer 1-n Pt::Event

# /app/models/pt/trainer.rb

class Pt::Trainer < ApplicationRecord
    has_many :pt_events # <- NameError uninitialized constant Pt::Trainer::PtEvent
end
# /app/models/pt/event.rb

class Pt::Event < ApplicationRecord
  belongs_to :pt_trainer # <- NameError uninitialized constant
end

エラー内容

これでevent側にデータ登録すると、NameErrorが出る。

NameError in Pt::EventsController#create
uninitialized constant Pt::Event::PtTrainer

また、trainer側でhas_manyのアソシエーションでデータ取得しようとすると同様のエラーが出る。(たとえば、rails consoleで「Pt::Trainer.all.includes(:pt_events)」と実行)

ptアプリ(成功例)

以下のように指定することで解決。

# /app/models/pt/trainer.rb

class Pt::Trainer < ApplicationRecord
  #has_many :pt_events # <- NameError uninitialized constant Pt::Trainer::PtEvent
  #has_many :pt_events, class_name: 'Pt::Event' # <- SQLite3::SQLException: no such column: pt_events.trainer_id: SELECT "pt_events".* FROM "pt_events" WHERE "pt_events"."trainer_id" IN (?, ?)
  has_many :pt_events, class_name: 'Pt::Event', foreign_key: :pt_trainer_id
end
# /app/models/pt/event.rb

class Pt::Event < ApplicationRecord
  #belongs_to :pt_trainer # <- NameError uninitialized constant
  belongs_to :pt_trainer, class_name: 'Pt::Trainer'
end

参考サイト

Namespaces in Rails Applications