0

Мне передали проект, над которым работал другой разработчик, не оставив никакой документации позади. Код извлекает некоторые покупки с торгового сайта, ищет цену и уведомляет пользователя.StandardError перенаправить на страницу

Приложение может столкнуться с ошибками, такими как «результаты не найдены», а затем я поднимаю стандартную ошибку.

Я хочу перенаправить пользователя на страницу с ошибкой и сообщить об этом, но я не могу этого сделать, потому что это не контроллер, поэтому опция redirect_to не работает.

услуги/purchase_checker.rb называется один раз в час:

 def call 
     user.transaction do 
      store_purchase 
      if better_purchase? 
      update_purchase 
      end 
     end 
     rescue MyError=> e 
     store_error(e) 
     end 



def store_error(error) 
    user.check_errors.create!(error_type: error.class.name, message: error.message) 
    end 

услуги/my_error.rb:

class MyError< StandardError 

    def initialize(error_type, error_message) 
    super(error_message) 
    @error_type = error_type 
    end 

    attr_reader :error_type 

end 

услуги/purchase_fetcher.rb:

def parse_result_page 
    raise purchase_form_page.error if purchase_form_page.error.present? 
    offer = purchase_page.map{|proposal_section| 
      propose(proposal_section, purchase) } 
          .min_by(&:price) 

    offer or raise MyError.new("No results", "No results could be found") 
    end 
+0

Вы можете разместить действие контроллера и где PurchaseChecker # вызов будет вызван? –

+0

это вызвано activejob – MaxDBN

+0

Что вы после неясно: если задание выполняется каждый час, где в цикле запроса/ответа вы предлагаете перенаправить пользователя? –

ответ

0

Так как это работает в работе, лучший способ уведомления пользователя будет по электронной почте, или какой-либо другой способ уведомления асинхронной. При обнаружении ошибки отправляется электронное письмо.

Если по какой-либо причине это не вариант, вы можете проверить, имеет ли пользователь check_errors в любых соответствующих контроллерах. Если посмотреть на метод store_error(error), который вызывается при обнаружении ошибки, кажется, что он создает новую запись в базе данных для регистрации ошибки. Вы должны быть в состоянии проверить, есть ли у пользователя ошибка, зарегистрированная через отношения user.check_errors.

Вы можете сделать это, как это, например:

class SomeController < ActionController::Base 
    # ... 
    before_action :redirect_if_check_errors 

    # ... 

    def redirect_if_check_errors 
    # Assuming you're using Devise or something similar 
    if current_user && current_user.check_errors.exists? 
     redirect_to some_error_page_you_create_for_this_path 
    end 
    end 
end 

Это будет проверять наличие этих ошибок в каждом действии SomeController и перенаправить пользователя на страницу ошибки, вы должны создать, где вы оказываете ошибки в отношения user.check_errors.

Существует несколько способов сделать это, но я по-прежнему считаю, что отправка электронной почты из задания является лучшим вариантом, если вы хотите активно уведомлять пользователя. Или, возможно, добавьте элемент интерфейса, который предупреждает пользователя, когда user.check_errors имеет материал, например.

1

вы должны создать другой класс ошибки, например NotFoundError:

offer or raise NotFoundError.new("No results", "No results could be found") 

затем в контроллере:

begin 
    parse_result_page 
rescue NotFoundError => e 
    redirect_to err_page, :notice => e.message 
end 
+0

У меня нет контроллера для этого объекта. Ошибка возникает в другом объекте. и потому что это не контроллер, я не могу использовать redirect – MaxDBN

+0

, если вы не хотите уведомить пользователя, чем вы не должны использовать фоновое задание, потому что оно асинхронно, вы не можете получить обратную связь вовремя –

+0

он выполнен первый раз сразу после того, как пользователь делает поиск .. тогда он должен уведомить его, нет результатов – MaxDBN

0

Я предлагаю вам сделать это синхронно, чтобы ответ мог произойти непосредственно в цикле запроса/ответа. Возможно, что-то вроде этого:

# controller

def search 
    # do your searching 
    # ... 
    if search_results.blank? 
    # call model method, but do it synchrously 
    purchase_check = PurchaseChecker.call 
    end 

    if purchase_check.is_a?(MyError) # Check if it's your error 
    redirect_to(some_path, flash: { warning: "Warn them"}) 
    end 
end 

# model, say PurchaseChecker

def call 
    # do your code 
rescue MyError => e 
    store_error(e) 
    e # return the error so that the controller can do something with it 
end 
Смежные вопросы