如何在不执行“before_save”的情况下更新属性?

8 浏览
0 Comments

如何在不执行“before_save”的情况下更新属性?

我在我的Message模型中定义了一个before_save,代码如下:\nclass Message < ActiveRecord::Base\n before_save lambda { foo(publisher); bar }\nend\n当我执行以下操作时:\nmy_message.update_attributes(:created_at => ...)\nfoo和bar会被执行。\n有时候,我想更新message的字段,但不执行foo和bar。\n如何更新数据库中的created_at字段而不执行foo和bar?

0
0 Comments

问题的原因是想要在使用"update_attributes"方法更新属性时不执行"before_save"回调函数。解决方法是使用"update_attribute"方法或者"update_all"方法,或者使用"touch"方法。

"update_attribute"方法可以用来更新单个属性的值,而不会触发任何回调函数。可以在api.rubyonrails.org上查看更多信息。

"update_all"方法可以用来更新多个属性的值,而不会触发任何回调函数。可以在edgeguides.rubyonrails.org上查看更多信息。

"touch"方法是一种优雅的方式,可以更新一个属性的值,但不触发任何回调函数。可以在api.rubyonrails.org上查看更多信息。

如果想要在更新属性时不执行"before_save"回调函数,可以使用"update_attribute"方法、"update_all"方法或者"touch"方法来实现。

0
0 Comments

在Rails中,当我们使用update_attributes方法更新模型实例时,通常会执行before_save回调。然而,有时我们希望在不执行before_save回调的情况下更新模型实例。这种情况下,我们可以使用update_all方法来实现。

update_all是Rails中的一个方法,可以用来更新多个模型实例的属性。这个方法不会触发模型的回调,因此不会执行before_save回调。

举个例子,如果我们想要更新一个名为my_message的消息实例的created_at属性,可以使用下面的代码:

my_message.update_all(:created_at => ...)

然而,上述代码会导致语法错误。解决这个问题的方法是使用update_all的另一种形式:

Message.update_all({:created_at => ...}, {:id => my_message.id})

使用这种方式,我们可以成功更新my_message实例的created_at属性,同时避免执行before_save回调。

值得注意的是,如果我们想要更新一个计数器属性,可以使用increment_counter方法来实现,这个方法也会跳过回调。

如果我们想要在不执行回调的情况下更新一个模型实例的属性,可以使用update_columnupdate_columns方法。

希望以上内容能帮助你解决如何在不执行before_save回调的情况下更新属性的问题。

0
0 Comments

问题的原因是在Rails 3.1版本中,使用update_column方法可以更新属性而不会执行before_save回调函数。而在其他版本中,可以通过设置一个标志位来绕过回调函数。

解决方法有两种:

1. 使用update_column方法来更新属性,这样就不会执行回调函数。但需要注意的是,使用update_column方法也意味着不会运行验证。

2. 设置一个标志位来跳过回调函数。首先在Message模型中添加一个类属性skip_callbacks,并在before_save回调函数中判断该标志位是否为true。然后可以通过设置该标志位的值来控制是否执行回调函数。可以针对多个记录设置该标志位,或者只对单个记录设置该标志位。

需要注意的是,使用update_column方法或设置标志位的方式都不适用于序列化的列。另外,使用update_column方法也会导致不运行验证。

关于设置一个属性在类中的讨论,可能不是线程安全的,建议仔细考虑。

0