【问题标题】:Accepts Nested Attribute with a virtual attribute接受带有虚拟属性的嵌套属性
【发布时间】:2011-04-09 00:44:53
【问题描述】:

我有一个项目模型,它接受任务的嵌套属性。并且Task有一个虚拟属性“name”。因此,每次我更改名称时,它都会在更新前作为 encrypted_task_name 持久化。在项目编辑页面上,表单有一个任务名称(而不是 encrypted_task_name)的输入字段。当我更改名称时,由于 name 是一个虚拟属性,Rails 不会检测到 Task 的更改,并且不会在更新 Project 时更新该任务。

即使在项目更新期间更改了任务的虚拟属性,我如何确保保存该任务?

我不想使用的一个选项是 task.rb 上的 :autosave => true 因为我的任务很少更新。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    我遇到了同样的问题。使用:autosave => true 甚至对我都不起作用。我设法通过将attribute_will_change!(:my_virtual_attribute) 添加到我的虚拟属性的作者来解决它。所以,在你的情况下:

    class Task < ActiveRecord::Base
      ..
      def name=(the_name)
        attribute_will_change!(:name)
        ..
      end
      ..
    end
    

    这会将对象标记为未更改或脏,这使得 update_attributes 正确保存嵌套模型。

    链接:

    http://apidock.com/rails/ActiveRecord/Dirty/attribute_will_change%21 http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects

    【讨论】:

    • 希望我能给你更多的支持。您知道当您不知道为什么会出现问题时,那么 SO 对您正在寻找的内容产生了确切的答案?是的,这只是发生在我身上。
    • 确实知道这种感觉。认为是时候自己提出其中一个答案了:-)。感谢您的支持!
    • 你救了我...这个问题要了我的命。
    【解决方案2】:

    对于 Rails 5.1 及更高版本,建议使用 attribute 而不是 attr_accessor,因为它会弄脏对象,从而触发验证。

    class Task < ActiveRecord::Base
      attribute :name, :string
    end
    

    【讨论】:

    【解决方案3】:

    总的来说,我推荐 RailsCasts.com - 第 167 和 16 集

    http://railscasts.com/episodes/167-more-on-virtual-attributes
    http://railscasts.com/episodes/16-virtual-attributes

    在第 167 集中,瑞恩做了非常相似的事情

    如果这没有帮助,您能否发布您的项目和任务模型的相关代码?

    【讨论】:

      【解决方案4】:

      查看Attribute Filters gem。它通过添加 attr_virtual DSL 关键字来处理虚拟属性跟踪(自动包装 setter 方法),并允许您执行其他操作,例如属性的声明式过滤:

      class User < ActiveRecord::Base
        include ActiveModel::AttributeFilters::Common::Split
      
        split_attribute   :real_name => [ :first_name, :last_name ]
        before_validation :filter_attributes
      
        attr_virtual  :real_name
        attr_accessor :real_name
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        相关资源
        最近更新 更多