ruby-on-rails 无法弄清楚如何在Rails中使用remote:true获取响应JSON

bq8i3lrv  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(90)

**更新:**我发现这个问题是一个库依赖问题。我没有安装jquery-rails gem,因此我不需要在我的应用程序中使用jquery-ujs库。简而言之,我使用jquery-ujs语法时,我只有内置的rails-ujs功能可用:((face-palm).感谢所有看过并提供和回答的人。

我觉得我在做一些相当基本的事情,但由于某种原因,我不能弄清楚我做错了什么。我能够通过使用form_for助手的remote: true选项成功地用AJAX异步创建记录。然而,我试图返回的简单JSON结构似乎在AJAX响应的data对象中不可用。当我运行console.log(data)时,我得到undefined在浏览器js控制台。
下面是我代码的一个相当准确的表示:
视图中的形式:

= form_for :thing, remote: true, html: { id: 'thing' } do |f|
      = f.text_field :name
      = f.submit 'submit'

字符串
我的控制器代码:

def create
    @thing = Thing.new(thing_params)

    if @thing.save
      render json: { message: 'Thank you' }
    else
      render json: { message: 'oh no' } 
    end
end


我的JavaScript/jQuery:

$(document).ready(function(){
      $('#thing').on('ajax:success', function(e, data, status, xhr) {
        console.log(data)
      }).on('ajax:error', function(e, xhr, status, error){
        console.log(error)
      });
})


我像疯了一样在谷歌上搜索,我只是不知所措。但也许有一些非常简单的东西我忽略了。我感谢任何建议。

to94eoyn

to94eoyn1#

Rails UJS默认使用application/javascript内容类型发送远程请求。
如果你想请求JSON,你可以给元素附加一个data-type="json"属性:

= form_for @thing, remote: true, html: { id: 'thing' }, data: { type: "json" } do |f|
  = f.text_field :name
  = f.submit 'submit'

字符串
还有一个Turbolinks的问题。你的代码直接将事件处理程序附加到元素上:

$('#thing').on('ajax:success', function(e, data, status, xhr) {
  console.log(data)
};


虽然这将在初始页面加载时起作用,但当Turbolinks用Ajax替换页面内容时,它将不起作用。相反,您需要创建一个幂等事件处理程序:

$(document).on('ajax:success', '#thing', function(e, data, status, xhr) {
  console.log(data);
}).on('ajax:error', '#thing', function(e, xhr, status, error){
  console.log(error);
});


这将事件处理程序附加到文档本身,它将在DOM冒泡时捕获事件。因此,您无需将此代码 Package 在$(document).ready(function(){ ... });中。
你还应该返回有意义的HTTP响应代码--这将决定Rails UJS是否触发ajax:successajax:error。而不是JSON消息,这是一个反模式。

def create
  @thing = Thing.new(thing_params)

  if @thing.save
    # Tell the client where the newly created object can be found
    head :created, location: @thing
    # or return a json representation of the object
    render json: @thing, status: :created
  else
    # just return a header 
    head :unprocessable_entity
    # or return a JSON object with the errors
    render json: { errors: @thing.errors }, status: :unprocessable_entity
  end
end

相关问题