#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:
- Сохраните ответ в переменной экземпляра
- переход к следующему действию
- Добавьте это в представление:
lt;% if @resp %gt; lt;%= @resp.body %gt; lt;% end %gt;