Rails冲突ajax和URI.encode

时间:2018-10-19 08:19:21

标签: ruby-on-rails ajax forms request

我有一个搜索字符串,该字符串通过控制器连接到我的书面库,并向第三方api发送get请求。形式:

<%= form_with(:url => url_for(:controller => 'orders', :action => 'find_drug'), method: "get") do %>
    <%= text_field_tag :drug_name, nil, class: "search_drug", placeholder:"Find drug..." %>
    <%= button_to "Find", nil, class: "search_drug_button" %>
<% end %>

Ajax:

$('document').ready(function() {
    $('.search_drug_button').click(function(){
        $.ajax({
                url: 'orders/find_drug',
            }).done(function(data) {
                console.log(data);
            });
        });
    });

控制器OrdersController:

def find_drug
        response = ApiParser::Parser.new
        drugs = response.get_drug(params[:drug_name]).response

        respond_to do |format|
            format.json { render json: drugs.body}
        end
    end

我的库中的方法(使用HTTParty gem编写):

module ApiParser
    class Parser
        include HTTParty
        ...
        def get_drug(drug)
            options = "?search.drugs={\"ls\": \"#{URI.encode(drug)}\"}"                                 
            self.class.get(options, format: :json)
        end
        ...    
    end
end

在控制台中,发送了2个请求(一种形式,直接发送到代码为200的控制器,第二种形式通过ajax),而ajax给我一个错误500

NoMethodError in OrdersController#find_drug

undefined method `gsub' for nil:NilClass
Extracted source (around line #305):

#303         unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
#304       end
*305       str.gsub(unsafe) do
#306         us = $&
#307         tmp = ''
#308         us.each_byte do |uc|

Extracted source (around line #104):

#102     def escape(*arg)
#103       warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
*104       DEFAULT_PARSER.escape(*arg)
#105     end
#106     alias encode escape
#107     #

Extracted source (around line #38):
                                             **#this is my code**
*38             options = "?search.drugs={\"ls\": \"#{URI.encode(drug)}\"}"                                 
#39             self.class.get(options, format: :json)

控制台Chrome 200中的请求:

...localhost:3000/orders/find_drug?utf8=%E2%9C%93&drug_name=%D1%8F%D1%80%&authenticity_token=Ndao2...

500:

...localhost:3000/orders/find_drug

如果在控制器中,我只是传递要查找的字符串,而不是 params [:drug_name] ,那么两个查询都可以使用代码200进行。写完整个问题后,我认为我的Ajax没有收到此特定的 params [:drug_name] ,并且无法搜索空值(但不完全是)。刚开始使用javascript

我试图执行这样的Ajax请求:

$('document').ready(function() {
  $('.search_drug_button').click(function(e){
    e.preventDefault();
    $.ajax({
      url: 'orders/find_drug',
      data: new FormData($(this).closest("form")[0])
    }).done(function(data){
      console.log(data);
    });
  });
});

但我遇到了错误

jquery-3.3.1.min.js:2 Uncaught TypeError: Illegal invocation
    at i (jquery-3.3.1.min.js:2)
    at jt (jquery-3.3.1.min.js:2)
    at Function.w.param (jquery-3.3.1.min.js:2)
    at Function.ajax (jquery-3.3.1.min.js:2)
    at HTMLInputElement.<anonymous> (Аптечная_сеть:551)
    at HTMLInputElement.dispatch (jquery-3.3.1.min.js:2)
    at HTMLInputElement.y.handle (jquery-3.3.1.min.js:2)

1 个答案:

答案 0 :(得分:1)

首先让我告诉您为什么您的代码无法正常工作。

  • 您正在同时使用表单和jQuery
  • 如果您想使用jQuery,则应使用event.preventDefault();来阻止所有在提交按钮上发生的默认操作,否则您将发送两个请求,一个使用默认表单提交,另一个使用jQuery。

解决方案:

您可以通过使用js.erb使用rails默认功能。

要使其正常工作。

在您的控制器代码中使用它。

def find_drug
  response = ApiParser::Parser.new
  @drugs = response.get_drug(params[:drug_name]).response
end
  • 注释掉您所有的ajax代码。
  • form_with(url: '/orders/find_drug', method: :get)替换代码
  • 在订单文件夹中以find_drug.js.erb创建文件
  • console.log('<%= @data %>');中写find_drug.js.erb

现在检查。如果您仍然遇到问题,请告诉我。