Rails Engineでマウントする側のモデルとされる側のモデルのassociation
目論見
MyAppという普通のRailsアプリにMyBlogというエンジンをマウントする。
MyAppにUser
モデルがあることをMyBlogが知っていると仮定(設定できるようにしたほうが良いけどとりあえず)。
MyBlogにはArticle
モデルがあり、User
には複数のArticle
を持たせたい。
belongs_to
belongs_to
は簡単で、Engine側のモデルに書けばいい。
module MyBlog class Article < ActiveRecord::Base belongs_to :user end end
has_many
こっちが問題で、User
クラスはマウントする側のアプリにいるので、EngineをマウントするためにMyAppのUser
モデルのコードをイジらなくてはいけない。とてもイケていない。
どうする
radar/foremのマネをしてdecoratorsを使う。
# my_blog.gemspec s.add_dependency 'decorators'
# app/decorators/lib/my_blog/user_class_decorator.rb MyBlog.decorate_user_class!
# lib/my_blog.rb require "my_blog/engine" require "decorators" module MyBlog class << self def decorate_user_class! MyBlog.user_class.class_eval do has_many :articles, class_name: "MyBlog::Article" end end def user_class Object.const_get("User") end end end
# lib/my_blog/engine.rb module MyBlog class Engine < ::Rails::Engine isolate_namespace MyBlog config.to_prepare do Decorators.register! Engine.root, Rails.root end end end
これで、マウントする側のコードを編集しなくてよくなった。
今回はUser
で固定だったところを指定できるようにすると、少しメタプロが必要かも。