【问题标题】:Ruby on Rails Inline around_save Callback Yields a LocalJumpErrorRuby on Rails 内联 around_save 回调产生 LocalJumpError
【发布时间】:2012-07-11 16:51:33
【问题描述】:

在 Rails 3.0.5 和 Ruby 1.9.3 中,是否可以在 around_save 声明中定义 around_save 回调的主体?

也就是说,我注意到这个案例可以正常工作:

around_save :around_save_body
def around_save_body
  puts 'before save'
  yield 
  puts 'after save'
end

[114] pry(main)> a = Activity.find(57)
=> #<Activity id: 57, ... >

[115] pry(main)> a.save
before save
after save
=> true

而如果我将正文内联,我会得到一个 LocalJumpError:

around_save do |activity|
  puts 'before save'
  yield 
  puts 'after save'
end

[117] pry(main)> a = Activity.find(57)
=> #<Activity id: 57, ... >

[118] pry(main)> a.save
before save
LocalJumpError: no block given (yield)
from /home/maksim/hkn/website/app/models/activity.rb:47:in `block in <class:Activity>'

我尝试在第二个示例中将yield 更改为yield activity,但得到了相同的结果。是否可以让我的 around_save 正文与 around_save 声明内联?

【问题讨论】:

    标签: ruby-on-rails ruby callback ruby-1.9


    【解决方案1】:

    在这种情况下,ActiveRecord 将传递 Proc 作为第二个参数,只需这样做:

    around_save do |activity, block|
      puts 'before save'
      block.call
      puts 'after save'
    end
    

    【讨论】:

    • 谢谢,这行得通。能否请您指出该语法的记录位置(或者是通过阅读源代码了解到的)?
    • 很遗憾,我找不到可以直接指向您的合适地点。这是一个反复试验,因为我只是怀疑 Ruby 会将传入的块作为第二个参数,因为您可以在定义的回调方法中使用yield。 Rails 中的回调内容令人困惑,但您可以在这里找到它们:github.com/rails/rails/blob/master/activemodel/lib/active_model/…github.com/rails/rails/blob/master/activesupport/lib/…
    • 我做了更多的测试,即使运行了,我也不确定它是否会产生正确的结果。这是一个更全面的示例,显示了我的实际输出与预期输出:pastie.org/4242079。你还有什么建议吗?我是否误解了这个回调应该如何工作?
    • 是的,您看到的结果就是预期的结果。在回调运行时,该值应该已经设置为 4。唯一能够检测到先前值的方法是使用ActiveModel::Dirty (api.rubyonrails.org/classes/ActiveModel/Dirty.html) 方法如point_waspoint_change 来获取设置之前的值。
    • 我看到这可以跟踪属性变化,但points_squared 是一个实例方法。有没有办法跟踪实例方法的变化,因为我不认为我可以在上面调用_was_change?还是我必须将其保存到属性中?
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多