简体   繁体   English

如何在父应用程序模型和挂载引擎模型之间设置has_many关联?

[英]How to set has_many association between parent app's model and mounted engine's model?

Following to RailsGuides instruction, I have created an engine for blogging system in my app. 按照RailsGuides指令,我在我的应用程序中创建了一个用于博客系统的引擎。 This blog engine is mounted as /blog. 此博客引擎安装为/ blog。

RailsGuides shows how to add belongs_to association to the mounted engine's Article model. RailsGuides显示了如何将belongs_to关联添加到已挂载引擎的Article模型。 However, the parent app's User model still requires has_many association to the engine's Article model which is in different namespace. 但是,父应用程序的User模型仍然需要has_many关联到引擎的Article模型,该模型位于不同的命名空间中。

How to set has_many association between parent app's model and mounted engine's model? 如何在父应用程序模型和挂载引擎模型之间设置has_many关联?

  • Ruby 2.2.0 Ruby 2.2.0
  • Rails 4.2.0 Rails 4.2.0

Thanks in advance. 提前致谢。

In the rails application, you know what module you include, so you can simply specify the relation with the class name ;) 在rails应用程序中,您知道包含哪个模块,因此您只需指定与类名称的关系;)

has_many :articles, class_name: 'Blog::Article'

check if this is the right syntax for your database adapter, eg I'm using this for Mongoid, but it should be the same with ActiveRecord AFAIK 检查这是否是您的数据库适配器的正确语法,例如我将其用于Mongoid,但它应该与ActiveRecord AFAIK相同

The accepted answer requires manual modification of main_app's parent model in order to set the has_many relationships to the engine's child model. 接受的答案需要手动修改main_app的父模型,以便将has_many关系设置为引擎的子模型。 So each time you add the engine to one your main_apps you would have to go into the main_apps models and set up all required relationships by hand. 因此,每次将引擎添加到main_apps中时,您都必须进入main_apps模型并手动设置所有必需的关系。

A more robust, although more complicated, solution would be to use the decorator pattern in the engine so that the engine will auto-configure main_app's parent model with the relationships it needs. 更强大但更复杂的解决方案是在引擎中使用装饰器模式,以便引擎将自动配置main_app的父模型及其所需的关系。

By using this method you just need to add a setting to the engine initializer in your main_app and the engine will handle the rest. 通过使用此方法,您只需要在main_app中为引擎初始化程序添加一个设置,引擎将处理其余的。

In engine: 在引擎中:

blog.gemspec.rb blog.gemspec.rb

s.add_dependency 'decorators' #this will install the decorators gem for use in engine

lib/blog/blog.rb 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 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

app/decorators/lib/blog/user_class_decorator.rb 应用程序/装饰/ 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

In main app: 在主应用程序中:

app/initializers/blog.rb 应用程序/初始化/ blog.rb

Blog.user_class = User

If you run rails console from main app, you will see relationships will have been set properly. 如果您从主应用程序运行rails控制台,您将看到关系已正确设置。 The decorator pattern in the engine can also be used to extend the main_app's models and controllers in different ways, not just Activerecord relationships. 引擎中的装饰器模式也可用于以不同方式扩展main_app的模型和控制器,而不仅仅是Activerecord关系。 Almost complete decoupling achieved! 实现了几乎完全解耦!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rails如何使用模型基于has_many关联基于“上一个活动”进行排序? - Rails how to sort based on “last activity” using a model and it's has_many association? 如何在has_many关联范围内访问模型的实例变量? - How can I access a model's instance variable within a has_many association scope? 在Rails 3.1中,如何检查模型的has_many关联的任何实例是否已更改? - In Rails 3.1 how can I check if any instances of a model's has_many association have changed? Rails has_many关联更改为父模型不会反映出来吗? - Rails has_many association changes into parent model dont reflect? Rails-在删除has_many模型时设置默认关联 - Rails - set default association on delete of has_many model Rails:如何检索模型的has_many对象作为集合? - Rails: How to retrieve a model's has_many objects as collection? 如何在没有其他查询的情况下通过关联对象的相关联接模型访问has_many:? - How can I access a has_many :through association object's relevant join model without additional queries? 如何通过取消选中复选框通过关联从父模型中移除has_many? - How to remove has_many through association from Parent model by unchecking checkbox? 如何覆盖has_many关联,以便显示父模型的默认值 - How to override a has_many association so it shows default values from a parent model 删除has_many:通过关联不会更改模型的updated_at属性 - Removing has_many :through association doesn't change model's updated_at attribute
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM