【发布时间】:2011-12-17 18:48:59
【问题描述】:
如何读取控制器在 before_save 回调中设置的值?
例子:
我有一个带有url 字段的模型。在保存之前,我想检查 url 是否已更改。如果是这样,请同时使用新网址和旧网址。
这可能吗?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1
如何读取控制器在 before_save 回调中设置的值?
例子:
我有一个带有url 字段的模型。在保存之前,我想检查 url 是否已更改。如果是这样,请同时使用新网址和旧网址。
这可能吗?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1
【讨论】:
url_changed?、url_was 和 url_change 方法很有趣。
更好的方法
before :todo, if: :first_name_or_last_name_changed?
还有你的 todo 方法
def first_name_or_last_name_changed?
first_name_changed? || last_name_changed?
结束
【讨论】:
如果它发生了变化,它应该在params 散列中。如果它没有改变,它不应该在那里。因此,您可以将此自定义处理放入控制器中,或者放入执行此操作的模型上的方法中。
如果您真的想在before_save 中访问它,请查看有关 ActiveRecord 回调的文档,您将了解如何访问之前和之后的值。
【讨论】:
url 被修改为设置不同属性的副作用,会发生什么?也许before_validation 钩子会查看其他属性并更新url,这与控制器无关。或者,before_save 可能被用于跟踪模型的修订历史,这也与控制器无关。
before_save 的方法。最初的提问者并没有真正进入他们想要根据 url 的值做的事情(例如,重定向到其他地方 - 在控制器中完成的事情),所以我不想假设目的是什么。我只是指出了您可以从哪些地方获得这些信息。
我试过这个东西,但没有成功
#Non-working code
before_save: record_old_value
after_save: record_change
def record_old_value
@old_value = self.field
end
def record_change
if @old_value==self.field
create_record_in_history :old_value => @old_value, :new_value => self.field
end
end
它没有成功的原因是因为我们设置了 self.field=new_value 所以在 before_save 中它是不可访问的。但是 rails 有更多的 Active-record 函数,比如 field_changed,可以直接在 before_save 和 after_save 中使用。所以我最终得到了这个解决方案
#working code
after_save :run_function
def run_function
@old_value = field_was
if @old_value==self.field
create_record_in_history :old_value => @old_value, :new_value => self.field
end
end
【讨论】: