覆盖默认访问者时更新属性的麻烦

我正在使用Ruby on Rails 4,我用这种方式覆盖了一些默认的访问器方法:

class Article < ActiveRecord::Base def title self.get_title end def content self.get_content end end 

self.get_titleself.get_content方法返回一些计算值,如下所示(注意: has_one_association是a :has_one ActiveRecord::Association

 def get_title self.has_one_association.title.presence || read_attribute(:title) end def get_content self.has_one_association.content.presence || read_attribute(:content) end 

当我从数据库中找到并读取@article实例时,所有实例都按预期工作: titlecontent值分别使用self.has_one_association.titleself.has_one_association.content输出。

但是,我发现当属性分配给@article ,@ @article对象不会按预期更新。 也就是说,在我的控制器中,我有:

 def update # params # => {:article => {:title => "New title", :content => "New content"})} ... # BEFORE UPDATING # @article.title # => "Old title" # Note: "Old title" come from the 'get_title' method since the 'title' accessor implementation # @article.content # => "Old content" # Note: "Old content" come from the 'get_content' method since the 'content' accessor implementation if @article.update_attributes(article_params) # AFTER UPDATING # @article.title # => "Old title" # @article.content # => "Old content" ... end end def article_params params.require(:article).permit(:title, :content) end 

即使@article有效,它还没有在数据库中更新 (!),我认为是因为我覆盖访问器的方式和/或Rails将assign_attributes的方式。 当然,如果我删除了getter方法,那么一切都按预期工作。

这是一个错误吗? 我该如何解决这个问题? 或者,我应该采用另一种方法来实现我想要实现的目标吗?


另见https://github.com/rails/rails/issues/14307

在这种情况下, update_attributes只是调用title=content=save的快捷方式。 如果你没有覆盖设置者,只是吸气剂,那就不相关了。

您正在更新这些值,但是Rails没有读取您正在设置的值,因为要覆盖要从关联中读取的getter。 您可以通过检查@article.attributes或查看数据库中的文章记录来validation这一点。

此外,您的get_content正在尝试read_attribute(:title)而不是:content