【问题标题】:Rails 5 throw abort : how do I setup error messages?Rails 5 throw abort:如何设置错误消息?
【发布时间】:2016-07-28 00:28:46
【问题描述】:

Rails 引入了这种throw(:abort) 语法,但现在我如何获得有意义的销毁错误?

对于验证错误,可以这样做

if not user.save
  # => user.errors has information

if not user.destroy
  # => user.errors is empty

这是我的模型

class User

  before_destroy :destroy_validation,
    if: :some_reason

  private

  def destroy_validation
    throw(:abort) if some_condition
  end

【问题讨论】:

    标签: activemodel ruby-on-rails-5


    【解决方案1】:

    您可以使用errors.add 作为您的类方法。

    用户模型:

    def destroy_validation
      if some_condition
        errors.add(:base, "can't be destroyed cause x,y or z")
        throw(:abort)
      end
    end
    

    用户控制器:

    def destroy
      if @user.destroy
        respond_to do |format|
          format.html { redirect_to users_path, notice: ':)' }
          format.json { head :no_content }
        end
      else
        respond_to do |format|
          format.html { redirect_to users_path, alert: ":( #{@user.errors[:base]}"}
        end
      end
    end
    

    【讨论】:

    • has_many 集合中销毁元素时并不完全正确, - 没有创建错误消息:post.comments.destroy(comment) 不会引发错误(至少在 Rails 控制台中)但 comment 元素在这种情况下不会被破坏。假设您有一个 Post 模型具有 has_many cmets 关系,并且您在声明 has_many 关系之前在 Post 模型中定义了 before_destroy 回调。
    【解决方案2】:

    Gonzalo S answer 完全没问题。但是,如果您想要更简洁的代码,您可以考虑使用辅助方法。以下代码在 Rails 5.0 或更高版本中效果最佳,因为您可以使用 ApplicationRecord 模型。

    class ApplicationRecord < ActiveRecord::Base
      self.abstract_class = true
    
    private
    
      def halt(tag: :abort, attr: :base, msg: nil)
        errors.add(attr, msg) if msg
        throw(tag)
      end
    
    end
    

    现在你可以这样做了:

    class User < ApplicationRecord
    
      before_destroy(if: :condition) { halt msg: 'Your message.' }
    
      # or if you have some longer condition:
      before_destroy if: -> { condition1 && condition2 && condition3 } do
        halt msg: 'Your message.'
      end
    
      # or more in lines with your example:
      before_destroy :destroy_validation, if: :some_reason
      
    private
    
      def destroy_validation
        halt msg: 'Your message.' if some_condition
      end
    
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多