代码之家  ›  专栏  ›  技术社区  ›  Craig Walker

阻止实例上的ActiveRecord save()

  •  8
  • Craig Walker  · 技术社区  · 16 年前

    我有一个ActiveRecord模型对象 Foo ; 它表示标准数据库行。

    我希望能够显示此对象实例的修改版本。我想重用类本身,因为它已经有了所有的钩子;我需要的方面(例如:我已经有了一个显示相应属性的视图)。基本上,我想克隆模型实例,修改它的一些属性,并将其反馈给调用者(视图、测试等)。

    希望这些属性修改回到数据库中。但是,我确实想包括 id 属性,因为它使处理路由助手变得更加容易。因此,我打算打电话给你 ActiveRecord::Base.clone() ,手动设置克隆实例的ID,然后对新实例进行相应的属性更改。这让我很担心;一 save() 在修改后的实例上,我的原始数据将被破坏。

    所以,我希望锁定新实例,这样就不会影响其他任何东西。我已经打算打电话了 freeze() (但有一项谅解,即这会阻止对对象的进一步修改,尽管 documentation isn't terribly clear ). 但是,我没有看到任何明显的方法来阻止save()。

    3 回复  |  直到 16 年前
        1
  •  22
  •   Fangxing    5 年前

    ActiveRecord::Base#readonly!

    model = MyModel.find 1
    model.readonly!
    model.save!
    

    它将引发ActiveRecord::ReadOnlyRecord

        2
  •  4
  •   Jimmy Nitzan Tomer    16 年前

    有一种更惯用的方法可以做到这一点,但有一种方法是设置虚拟属性并在 before_save 回拨。克隆对象时,设置虚拟属性 is_clone true 模型类的回调,如果设置了该属性,则会阻止保存。

        3
  •  4
  •   Craig Walker    16 年前

    freeze()

    x = Factory.create(:my_model)
    x.save!    # true
    x.freeze
    x.save!
    TypeError: can't modify frozen hash
    

    我猜save()正在尝试更新已创建/修改的属性,但由于属性哈希已冻结,因此失败。

    所以,冷冻会阻止保存。。。但我希望有一个更可靠的方法,有更具体的错误信息。