进行ajax POST并在Rails中返回JSON

时间:2017-11-11 03:35:20

标签: ruby-on-rails json ajax devise

我正在尝试向我的某个路由发出一个AJAX POST请求并返回一些JSON,但是我遇到了一个问题,即没有返回JSON而页面正在呈现而不是像GET请求一样。这是我的代码:

查看

<%= form_with url: users_add_skill_path, id: "skills-form", format: 'json' do |f| %>
  <%= f.text_field :skill, placeholder: "Submit your skill" %>
  <%= f.submit "Submit Skill" %>
<% end %>

这变成了HTML:

<form id="skills-form" action="/users/add_skill" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="token_hereadnfjahbsdkfjabsd">
    <label for="skill">Skill</label> 
    <input placeholder="Submit your skill" type="text" name="skill">

    <input type="submit" name="commit" value="Submit Skill" data-disable-with="Submit Skill">

</form>

路线

devise_scope :user do
    post '/users/add_skill' => 'users/registrations#add_skill', :defaults => 
{ :format => :json }
end

控制器

class Users::RegistrationsController < Devise::RegistrationsController

respond_to :html, except: [:add_skill]
respond_to :json, only: [:add_skill]    

def add_skill
  @user = current_user
  @user.skills.push(params[:skill])

  respond_to do |format|
    if @user.save
      format.json { render json: @user.skills, status: :created, location: @user }
    else
      format.json { render json: @user.errors, status: :unprocessable_entity }
  end
end

的Javascript

const skillsForm = document.getElementById("skills-form");
skillsForm.addEventListener('ajax:success', function(res) {
    console.log("added skill"); 
});

'技能'被持久化到数据库,所以我知道请求正确 - 如果我从路由中删除:defaults => { :format => :json},并更改{{1}中的其他一些内容}抱歉(对不起,我不记得我改变了什么),数据是持久的,页面没有改变,所以我很确定Ajax请求运行良好,但我不知道如何获得响应。

我看到很多使用jQuery ajax()的问题,但我没有使用jQuery,所以我不确定我应该做什么。任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:1)

我实际上意识到我没有在我的application.js中包含rails-ujs,因此请求是作为GET请求而没有返回任何内容。现在一切都已经解决了,感谢您的帮助。

答案 1 :(得分:0)

当你使用respond_to时,你应该尝试使用respond_with返回json,例如

class SomeController < ApplicationController
  respond_to :json


  def show
    @record = Record.find params[:id]

    respond_with @record
  end
end

,如果它仍然无效,请尝试添加方法::发布到您的表单并尝试。

答案 2 :(得分:0)

您的ajax代码似乎没问题但我在您的操作add_skill中看到了一些问题。您正试图通过属性哈希将新技能推向当前用户的现有技能。而是在用户的技能集合中构建技能,并尝试保存用户属性,如下所示:

def add_skill
  @user = current_user
  @user.skills.build(skill: params[:skill])

  respond_to do |format|
    if @user.save
      format.json { render json: @user.skills, status: :created, location: @user }
    else
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end
  • push(*records):通过将其外键设置为关联的主键,将一个或多个records添加到集合中。您提供给push的参数会产生ActiveRecord::AssociationTypeMismatch: Skill expected, got 'params[:skill]' which is an instance of String。有效的方式可能如下:
  

@ user.skills.push(Skill.new(skill:params [:skill]))

  • build(attributes = {}, &block):返回一个集合类型的新对象,该对象已使用attributes实例化并链接到此对象,但尚未保存。如果您使用此方法,则respond_to块会更有意义,因为在您致电@user.save之前,用户技能无法保存。

答案 3 :(得分:0)

首先,在您的eventListener

中将ajax:success替换为ajax:complete

您应该在表格html参数中添加remote: true,然后,您的请求将以您想要的格式回复(默认情况应该是&#39; JS&#39;)

例如:使用format: js,在控制器中执行

respond_to do |format|
  format.js { # TODO block }
end

最后使用send_data,您可以将数据发送到Ajax回调