使用此控制器/模型设置如何显示错误?

发布于 2024-12-07 10:49:01 字数 993 浏览 2 评论 0原文

我有一个创建方法,该方法调用模型中的一个方法来 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

I have a create method that calls a method in a model that pings some third-party APIs.

What I need to do is if the API sends back a certain message, then I'd display an error.

Below is my current controller and model setup, so how would I get the error back in to the controller (and ultimately the view)?

Here is the method in my controller:

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

Here are the methods in my model:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉睡月亮 2024-12-14 10:49:01

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

# 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

或者您可以将其作为验证的一部分来执行(因此调用 < code>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

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

How about if rather than throwing errors, you just use validation? Something like the following (Just to get your started. This would need work.):

# 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

Then in your controller:

@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

Alternatively you could do this as part of validation (so calling valid? would work as expected and not destroy your custom "track" errors)

# 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

Note in the latter case you'd have to change your logic a bit, and simply pass the tracking number and attempt to save a new record, which would trigger the tracking attempt.

凉宸 2024-12-14 10:49:01

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

You should typically offload the the API calls to a background job and you could either use notifiers (or Rack middleware) to raise self-defined errors and handle them accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文