Trouble on updating attributes when default accessors are overwritten

雨燕双飞 提交于 2020-01-06 14:11:12

问题


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 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

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.

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

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?


See also https://github.com/rails/rails/issues/14307


回答1:


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.

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.

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



来源:https://stackoverflow.com/questions/22239433/trouble-on-updating-attributes-when-default-accessors-are-overwritten

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!