为什么这是ReadOnly记录?

时间:2016-06-01 18:17:08

标签: ruby-on-rails activerecord

所以我通过一个主对象构建一个关联对象,如下所示: item.associated_items.build({name: "Machine", color: "Grey"})

然后在调用item.save的另一个方法中。但是我收到ActiveRecord::ReadOnlyRecord错误。我在文档中读到了

  

通过带有背驮式属性的连接加载的记录将被标记为只读,因为它们无法保存。

所以我认为这就是这里发生的事情。但

  1. 我不知道为什么会这样。我之前使用新的关联记录调用了一个对象,并且没有任何问题。

  2. 当他们说“背负属性”时,文档的含义是什么?

  3. 有没有办法通过item.associated_items.readonly(false).build(attributes)这样的方式来实现保存。我试过了,它没有用,但我希望还有另一种方式。

  4. 编辑:我刚试过 new_associated_item = AssociatedItem.new({attributes}) item.associated_items << new_associated_item

    和后面的方法调用 item.save 并且只读异常仍然会发生。

    edit2:MurifoX向我询问了如何加载Item。上面的代码发生在几个服务对象中。这个过程是

    控制器

    owner = Owner.includes(:medallions).references(:medallions).find_by_id(params[:id])
    

    creator = NoticeCreator.new(owner)
    creator.run
    

    NoticeCreator

    def initialize #effectively
        medallion_notice_creators = []
        owner.medallions.some_medallion_scope.each do |medallion|
            medallion_notice_creator = MedallionNoticeCreator.new(medallion)
            medallion_notice_creator.prepare
            medallion_notice_creators << medallion_notice_creator
        end
    end
    
    循环通过奖章通知创建者之后

    def prepare
        medallion.notices.build(attributes)
    end
    

    medallion_notice_creators.each do |medallion_notice_creator|
        medallion_notice_creator.medallion.save
    end
    

    如果代码看起来错综复杂,请道歉。有很多东西在进行,我正在尝试压缩代码并对其进行匿名化。

1 个答案:

答案 0 :(得分:0)

使用joinsincludes创建的对象(在您的情况下)被标记为只读,因为您正在使用连接和填充进行巨型查询并在主要对象中预加载嵌套对象。 (ActiveRecord可能会与许多属性混淆,并且不知道如何构建主对象,因此它会在其上标记readonly。)

正如您所注意到的,如果您使用简单的find创建对象,则不会发生这种情况,因为从查询中收到的唯一属性来自对象本身。

我不知道为什么你急于加载所有这些关联,也许它来自你代码中的某些规则,但你应该尝试使用owner创建一个简单的Owner.find(params[:id])对象,并且在需要时延迟加载关联,这样就可以在简单对象上构建嵌套关联并保存它们。