在 Rails 中,如何在加载子对象时自动加载父对象?

Posted

技术标签:

【中文标题】在 Rails 中,如何在加载子对象时自动加载父对象?【英文标题】:In Rails, how do I automatically load my parent object when the child object is loaded? 【发布时间】:2016-07-21 18:40:41 【问题描述】:

我使用的是 Rails 4.2.4。加载子对象时如何自动加载父对象?我有

class MyObject < ActiveRecord::Base
  belongs_to :address, class_name: 'Address', foreign_key: :address_id, :autosave => true, dependent: :destroy

但是当我打电话时

  @my_object = MyObject.find(params[:id])
  puts "address; #@my_object.address address_id: #@my_object.address_id"

输出是

address;  address_id: 6792

这意味着没有加载父对象,即使显然有一条地址记录与之相关。我希望它在我的模型时自动加载。我该怎么做?

编辑:响应wishalizer的建议,我将模型更改为

class MyObject < ActiveRecord::Base
    …
  belongs_to :address, inverse_of: :my_object

class Address < ActiveRecord::Base
  has_one :my_object, inverse_of: :address

但还是报错

NoMethodError (undefined method `includes' for #<MyObject:0x007fb7232415f8>):
  app/controllers/application_controller.rb:9:in `current_my_object'
  app/controllers/my_objects_controller.rb:5:in `edit'

在应用给出的建议时。

【问题讨论】:

【参考方案1】:

要在 ActiveRecord 关系中包含父关系,请在控制器中创建集合时使用 .includes。 .includes 是对称的,无论是从父母到孩子还是从孩子到父母。

如果您显式调用.includes,那么您应该能够根据需要从子集合中引用父集合。

@my_object = MyObject.find(params[:id]).includes(:address)

需要模型关系 [新部分]

inverse_of 附加/插入到您的模型关系定义中

    Class MyObject  
        belongs_to :address, ...your model rels.., inverse_of: :my_object
        ...
    end

您还必须在相关模型中创建对称的inverse_of

   Class Address
       has_many :my_objects, ...your model rels.., inverse_of: :address
      ...
   end

【讨论】:

我将我的行更改为您所拥有的“@my_object = MyObject.find(params[:id]).includes(:address)”,但收到错误“NoMethodError (undefined method `includes ' 对于 #<0x007f8981738d38> 【参考方案2】:

请看一下。如果我弄错了,请纠正我

MyObject.includes(:address).references(:address)

【讨论】:

【参考方案3】:

但是当我打电话时

@my_object = MyObject.find(params[:id])
puts "address; #@my_object.address address_id: #>@my_object.address_id"

输出是

address;  address_id: 6792

调用@my_object.address其实就是加载地址记录。 @my_object.address 显示空白的一种可能情况是 addressid=6792 不存在。

为了更正 Val Asensio(wishalizer?)的建议以修复 NoMethodError,请将 includes() 函数移动到正确的位置:

@my_object = MyObject.includes(:address).find(params[:id])

【讨论】:

以上是关于在 Rails 中,如何在加载子对象时自动加载父对象?的主要内容,如果未能解决你的问题,请参考以下文章

记录 Umi通过配置 dynamicImport loadingComponent 实现加载效果

如何在角度2中默认加载子路由

Delphi动态加载子窗体名到MainMemu进行窗体切换

实体框架 - 连接新添加的 Poco 实体并加载子对象(插入/添加)

如何在 Rails 中自动链接到文本提交中的对象

Rails 项目中不断自动加载的问题(偶尔工作)