Rails:向after_save回调中生成的用户显示错误

时间:2017-07-24 21:49:49

标签: ruby-on-rails

如何解决在after_save回调中生成的错误,然后最终将其显示给用户?我的模型中的代码如下所示:

Class MyModel
  after_save :call_other_class_responsible_for_parsing

  def call_other_class_responsible_for_parsing
    # this method is used by multiple models
    ModelTwo.parse_css
  end
end

在我的控制器中,如果更新成功,我目前将用户重定向到其他位置,但是,如果它通过所有现有验证并且,则认为更新成功回调(来自Less :: Parser)。

编辑:

我在原来的问题中混淆了我的想法。 MyModel从它的相应控制器中保存,然后从模型运行after_save回调。在call_other_class_responsible_for_parsing中,有一个对另一个模型的调用,比如ModelTwo,它执行Less解析。我尝试过使用这样的代码:

  def self.parse_css
    @my_model = MyModel.find(1)
    css_to_compile = Less::Parser.new.parse(css).to_css
    rescue Less::Error => error
      @my_model.errors[:base] << "Error message"    
      false
    end
  end

但是false并不会阻止事务成功,因此会发生重定向。

2 个答案:

答案 0 :(得分:0)

您可以使用交易:

def create
  MyModel.transaction do
    @my_model.save
    @my_model.my_method
  end
  rescue ActiveRecord::RecordInvalid => exception
    # rescue active record exception here
  rescue Less::Error => exception
    # rescue less error here
end

这消除了回拨的需要。

我希望这有帮助!

答案 1 :(得分:0)

回调链隐式包装在事务中。当回调返回false或引发异常时,整个事务将回滚并保存失败。

在你的情况下,你正在解析一些CSS,所以我不确定after_save是否适合这个。 我建议您尝试验证。请考虑以下事项:

class MyModel < ActiveRecord::Base
  validate :valid_css

  private

  def parsed_css
    @parsed_css ||= Less::Parser.new.parse(css).to_css
  end

  def valid_css
    parsed_css
  rescue Less::Error => error
    errors.add(:css, "Cannot parse CSS: #{error}")
  end
end

这将在保存对象之前解析CSS ,如果它无效则添加错误。此外,#to_css的结果将被存储,以便您不必重新计算它。 这是我推荐的方法

如果您想坚持after_save,那么您应提出异常以中止交易。在您的情况下,它只是没有拯救Less::Error

class MyModel < ActiveRecord::Base
  after_save :compile_css

  private

  def compile_css
    css_to_compile = Less::Parser.new.parse(css).to_css
  end
end

如果您在决定使用哪种方法时遇到问题,请在下方留下问题,我会帮助您。