我有一个Project模型,它接受任务的嵌套属性。而Task有一个虚拟属性“name”。因此,每次更改名称时,它都会在更新前保持为encrypted_task_name。在项目编辑页面上,表单具有任务名称的输入字段(而不是encrypted_task_name)。当我更改名称并且因为name是虚拟属性时,Rails不检测任务中的更改,并且在更新Project时不会更新该任务。
如果在项目更新期间更改了虚拟属性,如何确保保存任务?
我不想使用的一个选项是:autosave =>在task.rb上为true,因为我的任务很少更新。
答案 0 :(得分:26)
我遇到了同样的问题。使用: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
答案 1 :(得分:0)
一般来说,我推荐RailsCasts.com - 第167和第16集
http://railscasts.com/episodes/167-more-on-virtual-attributes和
http://railscasts.com/episodes/16-virtual-attributes
在第167集中,Ryan做了类似的事情
如果这没有帮助,您可以发布项目和任务模型的相关代码吗?
答案 2 :(得分:0)
查看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
答案 3 :(得分:0)
对于Rails 5.1及更高版本,建议使用attribute
而不是attr_accessor
,因为它会使对象变脏,从而触发验证。
class Task < ActiveRecord::Base
attribute :name, :string
end