覆盖默认访问器时更新属性时出现问题 [英] Trouble on updating attributes when default accessors are overwritten

查看:87
本文介绍了覆盖默认访问器时更新属性时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Ruby on Rails 4 and I have overwritten some default accessor method this way:

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:has_one ActiveRecord::Association)

self.get_title and self.get_content methods return some computed value and look like the following (note: has_one_association is 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输出.

When I find and read @article instances from the database all works as expected: title and content values are respectively outputted with self.has_one_association.title and self.has_one_association.content.

但是,我发现,当将属性分配给@article时,@article对象将得到 not 的预期更新.也就是说,在我的控制器中,我有:

However, I found that when attributes are assigned to an @article then the @article object is not updated as expected. That is, given in my controller I have:

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方法,那么所有方法都会按预期工作.

Even if the @article is valid it has not been updated in the database (!), I think because the way I overwrite accessors and/or the way Rails would assign_attributes. Of course, if I remove the getter methods then all works as expected.

这是一个错误吗?我该如何解决这个问题?或者,我应该采用另一种方法来完成我想完成的工作吗?

Is it a bug? How can I solve the problem? Or, should I adopt another approach in order to make what I would like to accomplish?

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

推荐答案

update_attributes只是调用title=content=save的快捷方式.如果您不覆盖设置器,仅覆盖获取器,则不相关.

update_attributes in this case is just a shortcut for calling title=, content=, and save. If you're not overwriting the setters, just the getters, it is not related.

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

You're updating the values correctly, but Rails isn't reading the values you're setting, due to overwriting the getters to read from the association instead. You could verify this by checking @article.attributes, or looking at the article record in the database.

此外,您的get_content尝试使用read_attribute(:title)而不是:content.

Also, your get_content is trying to read_attribute(:title) instead of :content.

这篇关于覆盖默认访问器时更新属性时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆