【问题标题】:How would I get an error to display with this controller/model setup?使用此控制器/模型设置如何显示错误?
【发布时间】:2011-11-29 15:40:18
【问题描述】:

我有一个 create 方法,它调用模型中的一个方法来 ping 一些第三方 API。

我需要做的是,如果 API 发回某个消息,那么我会显示一个错误。

以下是我当前的控制器和模型设置,那么我如何将错误返回到控制器(以及最终的视图)?

这是我的控制器中的方法:

def create
  @number = Number.where(:tracking => params[:number][:tracking], :user_id => current_user.id).first

  if @number.blank?
    @number = Number.new
    @number.tracking = params[:number][:tracking]
    @number.user_id = current_user.id
    @number.notes = params[:number][:notes]
    @number.track
  end

  respond_with(@number) do |format|  
    format.html { redirect_to root_path }  
  end
end

这是我模型中的方法:

def track
  create_events
end


def create_events(&block)

  tracker = fedex.track(:tracking_number => number)

  if tracker.valid?    
    self.assign_tracker(tracker)

    tracker.events.each do |e|
      self.create_event(e) unless (block_given? && !block.call(e))
    end

    save
  else
    # NEED TO THROW THE ERROR HERE
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 model-view-controller error-handling


    【解决方案1】:

    如果你不抛出错误,而只使用验证呢?类似于以下内容(只是为了让您开始。这需要工作。):

    # if you don't cache the tracker in an attribute already, do this so
    # you can add errors as if it were a column.
    attr_accessor :tracker
    
    def create_events(&block)
    
      tracker = fedex.track(:tracking_number => number)
    
      if tracker.valid?    
        # ...
      else
        # add the error with i18n
        errors.add(:tracker, :error_type_if_you_know_it)
    
        # or add it from a returned message
        errors.add(:tracker, nil, :message => fedex.get_error())
      end
    end
    

    然后在你的控制器中:

    @number.track
    
    respond_with(@number) do |format|
      if @number.errors.any?
        format.html { redirect_to root_path }
      else
        format.html { render :some_template_with_errors }
      end
    end
    

    或者您可以将其作为验证的一部分(因此调用 valid? 将按预期工作,并且不会破坏您的自定义“跟踪”错误)

    # do your tracking on creation, if number was given
    validate :on => :create do
      if number.present?
        tracker = fedex.track(:tracking_number => number)
        unless tracker.valid?
          errors.add :tracker, nil, :message => tracker.get_error()
        end
      end
    end
    
    # then do your actual creation of tracking events sometime after validation
    before_save :handle_tracker_assignment
    
    def handle_tracker_assignment
      self.assign_tracker(tracker)
      # note the block method you're using would need to be reworked
      # ...
    end
    

    请注意,在后一种情况下,您必须稍微更改逻辑,只需传递跟踪号并尝试保存新记录,这将触发跟踪尝试。

    【讨论】:

    • @number.valid? 在控制器中返回 true 而模型中的 tracker.valid? 返回 false。
    • 对不起,调用valid? 实际上会清除错误并重新验证,这会转储自定义错误。编辑答案。
    【解决方案2】:

    您通常应该将 API 调用卸载到后台作业,并且您可以使用通知程序(或 Rack 中间件)来引发自定义错误并相应地处理它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多