接受带有虚拟属性的嵌套属性

发布于 2024-10-31 04:18:01 字数 269 浏览 0 评论 0原文

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

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

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

I have a Project model which accepts nested attributes for tasks. And Task has a virtual attribute "name". So every time I change the name, it gets persisted as encrypted_task_name before update. On the project edit page the form has a input field for task name (and not encrypted_task_name). When I change the name and since name is a virtual attribute, Rails doesn't detect a change in Task and doesn't update that task while updating Project.

How do I make sure that task is saved even if its virtual attributes are changed during Project update?

One option that I don't want to use is :autosave => true on task.rb since I task is rarely updated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

染年凉城似染瑾 2024-11-07 04:18:01

我遇到了同样的问题。使用 :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

I ran into the same problem. Using :autosave => true didn't even work for me. I managed to solve it by adding attribute_will_change!(:my_virtual_attribute) to the writer for my virtual attribute. So, in your case:

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

This marks the object as unchanged or dirty, and that makes update_attributes save the nested model correctly.

Links:

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

带刺的爱情 2024-11-07 04:18:01

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

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

For Rails 5.1 and up it's advisable to use attribute instead of attr_accessor as it dirties up the object, thus triggering the validation.

class Task < ActiveRecord::Base
  attribute :name, :string
end
往事风中埋 2024-11-07 04:18:01

一般来说,我推荐 RailsCasts.com - 第 167 集和第 16 集

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

在第 167 集中,Ryan 做了一些非常类似的事情。

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

In general, I'd recommend RailsCasts.com - episodes 167 and 16

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

In episode 167, Ryan does something very similar

If this doesn't help, could you post the relevant code for your Project and Task models?

暖树树初阳… 2024-11-07 04:18:01

查看属性过滤器 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

Check out Attribute Filters gem. It takes care of virtual attributes tracking (automagically wrapping setter methods) by adding attr_virtual DSL keyword and lets you do other things, like declarative filtering of attributes:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文