[misc][tips][Rails] ネストしたリレーションとモジュール化されたActiveRecordの名前

リリース予定に間にあってないのでいいわけエントリーを作るw

どうも、Railsのload_missing_constant の動作が怪しい。「普通に」やればいいんだけど、普通じゃない使い方をしているので。Rails 2.0にあげたせいかな?とも思ったんだけど、根本的にlaod_missing_constantがいけない感じ。モジュール化(Prefixがつく)ActiveRecordを使いたい貴方は注意ってことか。

  • RAILS_ROOT/component ディレクトリにパスを通す。
  • RAILS_ROOT/component/blog/blog_setting.rb に Blog::BlogSetting クラスを定義する
  • RAILS_ROOT/component/blog/blog_entry.rb に Blog::BlogEntry クラスを定義する
  • RAILS_ROOT/app/model/wj_relationship_permission_key.rb に WjRelationshipPermissionKey クラスを定義する

エンティティの関連を次のように定義する。

# components/blog/blog_setting.rb
class Blog::BlogSetting
  has_many :wj_relationship_permission_keys, :as => :wj_relationship_permittable, :dependent => :destroy
  has_many :blog_entries
end

# components/blog/blog_entry.rb
class Blog::BlogEntry
  belongs_to :blog_setting
end

でこの状態で、

blog = Blog::BlogSetting.new

これはOK。

Blog::BlogSetting.find(:all, :include => [:wj_relationship_permission_keys]

OK

Blog::BlogEntry.find(:all, :include => [:blog_setting]

OK

Blog::BlogEntry.find(:all, :include => {:blog_setting => :wj_relationship_permission_keys}

NameError "components/blog/blog_setting.rb to be defined BlogSetting" となる罠。。。load_missing_constant で落ちているので実装を観てみるが、どうもパスの解決がおかしいっぽい。深くはみていないが、どうもクラス名のプレフィックスの解決がちゃんと実装されていないようなので、

-  belongs_to :blog_setting
+  belongs_to :blog_setting, :class_name => "Blog::BlogSetting"

で解決する。