如何在父应用程序模型和挂载引擎模型之间设置has_many关联?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在父应用程序模型和挂载引擎模型之间设置has_many关联?相关的知识,希望对你有一定的参考价值。
继RailsGuides指令之后,我在我的应用程序中创建了一个用于博客系统的引擎。此博客引擎安装为/ blog。
RailsGuides显示如何将belongs_to
关联添加到已安装引擎的Article
模型。但是,父应用程序的User
模型仍然需要has_many
关联到引擎的Article
模型,该模型位于不同的命名空间中。
如何在父应用程序模型和挂载引擎模型之间设置has_many关联?
- Ruby 2.2.0
- Rails 4.2.0
提前致谢。
在rails应用程序中,您知道包含哪个模块,因此您只需指定与类名称的关系;)
has_many :articles, class_name: 'Blog::Article'
检查这是否是数据库适配器的正确语法,例如我将它用于Mongoid,但它应该与ActiveRecord AFAIK相同
接受的答案需要手动修改main_app的父模型,以便将has_many关系设置为引擎的子模型。因此,每次将引擎添加到main_apps中时,您都必须进入main_apps模型并手动设置所有必需的关系。
更强大但更复杂的解决方案是在引擎中使用装饰器模式,以便引擎将自动配置main_app的父模型及其所需的关系。
通过使用此方法,您只需要在main_app中为引擎初始化程序添加一个设置,引擎将处理其余的。
在引擎中:
blog.gemspec.rb
s.add_dependency 'decorators' #this will install the decorators gem for use in engine
LIB /博客/ blog.rb
module Blog
class Engine < ::Rails::Engine
isolate_namespace Blog
engine_name 'blog'
#to set up main_app objects via decorators in engine
config.to_prepare do
Decorators.register! Engine.root, Rails.root
end
end
end
LIB / blog.rb
require 'decorators'
module Blog
mattr_accessor :user_class #Can now reference this setting as Blog.user_class
class << self
#the following lets us add functionality to main_app user model
def decorate_user_class!
Blog.user_class.class_eval do
has_many :articles, :class_name => "Blog::Article", :foreign_key => "user_id"
end
end
end
end
应用程序/装饰/ lib目录/博客/ user_class_decorator.rb
if Blog.user_class
Blog.decorate_user_class!
else
raise "Blog.user_class must be set in main_app blog.rb initializer"
end
在主应用程序中:
应用程序/初始化/ blog.rb
Blog.user_class = User
如果您从主应用程序运行rails控制台,您将看到关系已正确设置。引擎中的装饰器模式也可用于以不同方式扩展main_app的模型和控制器,而不仅仅是Activerecord关系。实现了几乎完全解耦!
以上是关于如何在父应用程序模型和挂载引擎模型之间设置has_many关联?的主要内容,如果未能解决你的问题,请参考以下文章
有关如何使用has_many:through关系正确设置验证的指导?
如何在has_many中获取模型的属性:通过Rails 5中的关联