Использование контроллеров Rails для выполнения веб-запроса, а затем отображения данных

#ruby-on-rails #ruby #web #networking #stimulusjs

#рубин на рельсах #рубин #сеть #сетевой #стимулятор

Вопрос:

У меня есть контроллер rails, который делает веб-запрос, я хотел бы отобразить тело ответа и код состояния внутри представления без сохранения данных в модели. Я пробовал использовать частичные и переменные экземпляра, но мне не повезло.

Вот что у меня есть до сих пор:

 def create  uri = URI.parse "https://#{login_params[:ip]}"  http = Net::HTTP.new uri.host, uri.port   http.use_ssl = true if uri.scheme == 'https' # Use SSL, Should probably be default  http.verify_mode = OpenSSL::SSL::VERIFY_NONE   req = Net::HTTP::Post.new(uri.request_uri, headers)  req.basic_auth login_params[:username].to_s, login_params[:password].to_s # Base64 encode username:password    res = http.request(req, req_body) # make request   body = Hash.from_xml(res.body)  if res.code == 200  redirect_to :show  end  end  

Может быть, мне просто лучше сделать запрос с помощью стимула JS и добавить данные на экран?

Комментарии:

1. Не выполняйте HTTP-запросы, встроенные в ваш контроллер. В любом случае у него достаточно ответственности, и контроллеры, как известно, трудно проверить. Создайте отдельный клиентский объект (обычный старый объект ruby), который касается границ приложения, которые вы можете тестировать изолированно, просто передавая в него входные данные. Кроме того, это потенциально вектор атаки для хакера — поскольку вы используете IP-адрес, злоумышленник может отправить запрос на любой сервер, находящийся под его контролем, а затем использовать уязвимости в анализаторе XML. Зачем вам нужно получать IP-адрес с интерфейса?

2. Это просто спецификация, о которой просил мой клиент.

3. Должен ли я использовать модуль или класс, все еще не понимая затрат/выгод между ними.

4. класс. Классы, которым вы позволяете создавать экземпляры и инкапсулировать данные.

Ответ №1:

ваша проблема здесь в том, что вы не присваиваете значение вашего запроса переменной экземпляра, например, вы могли бы это сделать:

 def create  uri = URI.parse "https://#{login_params[:ip]}"  http = Net::HTTP.new uri.host, uri.port   http.use_ssl = true if uri.scheme == 'https' # Use SSL, Should probably be default  http.verify_mode = OpenSSL::SSL::VERIFY_NONE   req = Net::HTTP::Post.new(uri.request_uri, headers)  req.basic_auth login_params[:username].to_s, login_params[:password].to_s # Base64 encode username:password    res = http.request(req, req_body) # make request   @body = Hash.from_xml(res.body)  @code = res.code   if res.code == 200  redirect_to :show  end  end  

затем получите доступ к нему из такого представления:

 lt;%= @body %gt; lt;%= @code %gt;  

Комментарии:

1. нужно ли мне также добавлять переменные экземпляра в действие «показать»?

2. Поскольку вы не сохраняете результат своего запроса, вам нужно будет повторить вызов API. Я бы предложил извлечь запрос в частный метод, а затем вызвать его с вашего контроллера. Вы можете использовать на нем некоторый кэш, чтобы избежать двойного запроса. Опубликуйте свой контроллер, и я добавлю свои предложения

Ответ №2:

  1. Сохраните ответ в переменной экземпляра
  2. переход к следующему действию
  3. Добавьте это в представление:
 lt;% if @resp %gt;   lt;%= @resp.body %gt;  lt;% end %gt;