1

Is there a more elegant way to do this:

widget.notes.where(:author_id => a).first.message= widget.notes.where(:author_id => a).first.message << "Potato"

For example, the following do not work:

widget.notes.where(:author_id => a).first.message << "Potato"
widget.notes.where(:author_id => a).first.message <<! "Potato"

Respectively not modifying, or returning an error (as there is no

<<!

operator)

key: widget is an instance of Widget. Widgets can have notes. Notes have an attr_accessible for :message. 'a' is just a user instance.


This is not a problem of << not modifying the string in-place - it does modify the string in-place. << might not have a ! in its name, but it still acts like a bang-method. You can see this easily if you replace << with a call to gsub! (which does have a ! in its name) in your example code: it won't make a bit of difference.

In your case you get back the unchanged string because widget.notes.where(:author_id => a).first presumably returns a new object each time, which will have its own independent string.

Further, if message corresponds to a database column, not an instance variable, I'm not sure whether calling mutating methods on it will even work as it would circumvent calling ActiveRecord's (or whichever ORM you're using) setter methods. Using += might be your safest bet here.

This should work as you want:

note = widget.notes.where(:author_id => a).first
note.message += "Potato"
note.save
4

1 回答 1

3

这不是<<不就地修改字符串的问题——它确实就地修改了字符串。<<它的名称中可能没有 a !,但它仍然像 bang-method 一样。如果您在示例代码中替换为对(名称中确实有 a )<<的调用,您可以很容易地看到这一点:它不会产生任何影响。gsub!!

在您的情况下,您会返回未更改的字符串,因为 widget.notes.where(:author_id => a).first 可能每次都会返回一个新对象,该对象将具有自己的独立字符串。

此外,如果message对应于数据库列,而不是实例变量,我不确定在其上调用变异方法是否会起作用,因为它会绕过调用 ActiveRecord(或您正在使用的任何 ORM)setter 方法。在这里使用+=可能是您最安全的选择。

这应该可以按您的意愿工作:

note = widget.notes.where(:author_id => a).first
note.message += "Potato"
note.save
于 2012-12-21T11:59:43.543 回答