覆盖默认访问器时更新属性时出现问题 [英] Trouble on updating attributes when default accessors are overwritten
问题描述
我正在使用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_title
和self.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
实例时,所有实例均按预期工作:title
和content
值分别通过self.has_one_association.title
和self.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屋!