使用JSON通过ajax请求传递Rails参数

4
我正在使用Rails 5.2,并希望有一个国家和城市选择表单。我使用city-state gem来创建下拉菜单,其中包含所有国家和城市,但是城市下拉菜单需要事先知道所选的国家。
我认为最好使用ajax来通过下拉菜单上的输入事件监听器传递所选国家。但是我的问题是,ajax请求没有传递我编写的JSON变量,而是传递了{"object Object"=>nil, "id"=>"1"}
目前我的代码如下:
    <%= form_with(model: @user) do |form| %>
    <%= form.select :country, CS.countries.values.sort, { :prompt => 'Country'} %>
    <%= form.select :city, CS.states('placeholder').keys.flat_map { |state| CS.cities(state, 'placeholder') }, { :prompt => 'City'} %>
    <%= form.submit %>
<% end %>

<script>
    var countryForm = document.getElementById('user_country');
    countryForm.addEventListener('input', function (evt) {
    var country = this.value;
    Rails.ajax({
        type: "GET",
        url: '/users/' + <%= params[:id] %> + '/country',
        dataType:'json',
        data : {'country': country},
        error: function (xhr, status, error) {
            console.log('error')
            console.error('AJAX Error: ' + status + error);
        },
        success: function (response) {
        }
    });
});
</script>

以下是请求后在控制台中看到的内容:
   Started GET "/users/1/country?[object%20Object]" for 127.0.0.1 at 2018-06-13 13:19:50 +0200
Processing by UsersController#country as JSON
  Parameters: {"object Object"=>nil, "id"=>"1"}
Completed 204 No Content in 1ms (ActiveRecord: 0.0ms)

有没有想法我做错了什么?我已经试图到处寻找,但是我没有看到任何关于如何在Ajax中使用JSON的Rails 5指南。请帮忙。谢谢。

3个回答

7

在到处搜索后,我在这个链接上找到了解决方案: https://learnetto.com/blog/how-to-make-ajax-calls-in-rails-5-1-with-or-without-jquery

请求的代码可以编写如下:

Rails.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(repsonse){...},
  error: function(repsonse){...}
})

但是有一个问题!据我所知,您无法简单地发送JSON数据。因此,我们需要手动将mydata转换为应用程序/x-www-form-urlencoded内容类型,像这样:

mydata = 'thing[field1]=value1&thing[field2]=value2'

当我这样做时,我以正确的方式获取参数:
 Parameters: {"thing"=>{"field1"=>"value1", "field2"=>"value2"}, "id"=>"1"}

显然,在jQuery时代发生了数据对象的自动转换,但在rails-ujs版本中缺少该功能。


噢,不错的发现 - 希望很快会被修复。 - SRack

4

我遇到了一个类似的问题。然后我了解了URLSearchParams接口,该接口被所有现代浏览器支持。

Rails.ajax({
  type: 'GET',
  url: '/users/' + <%= params[:id] %> + '/country',
  data: new URLSearchParams({'country': country}).toString(),
  success: function (response) {
    // ...
  }
})

2

使用 JSON.stringify() 处理你的数据:

data: JSON.stringify({'country': country}),

您目前传递的是一个对象,而不是JSON,这会导致问题。我相信这个方法可以为您解决问题。

您的id参数是正确的,因为它通过URL传递,但数据本身需要以JSON字符串形式传递。


2
嘿,谢谢你的回复。我尝试过了,但我的字符串化对象输出不正确: Parameters: {"{\"country\":\"Algeria\"}"=>nil, "id"=>"1"} 有什么想法吗? - Laurence
哎呀,这真的很奇怪。Rails.ajax 的来源是什么?它可能是内置的,我只是没听说过 - 不过如果不是,那么传递数据的方式可能存在问题。 - SRack
据我所了解,Rails.ajax是Rails 5中不使用jQuery进行Ajax请求的方式。我应该在哪里查找源代码? - Laurence
啊 - 你可能是对的。我有一份新工作,我们使用Rails 4,所以还没有遇到过这个问题。如果我想到了什么,我会告诉你的,感谢澄清。 - SRack
无论如何,我真的无法理解这种行为。如果我找到了解决方案,我会在这里发布。 - Laurence
解决方法是使用 URLSearchParams,如 @Andrew 的答案中所提到的。 - charlesdeb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接