代码之家  ›  专栏  ›  技术社区  ›  mcheah

在Rails中发布ajax并返回JSON

  •  1
  • mcheah  · 技术社区  · 8 年前

    我试图向我的一条路由发出一个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} 从路线,并改变了其他一些事情在 respond_to block(抱歉,我不记得我到底更改了什么),数据被持久化了,页面没有更改,因此我很确定Ajax请求工作正常,但我不知道如何获得响应。

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

    4 回复  |  直到 8 年前
        1
  •  1
  •   mcheah    8 年前

    我实际上意识到我没有包括 rails-ujs

        2
  •  0
  •   Aaquib Khan    8 年前

    例如,当您使用respond\u to时,您应该尝试使用respond\u with返回json

    class SomeController < ApplicationController
      respond_to :json
    
    
      def show
        @record = Record.find params[:id]
    
        respond_with @record
      end
    end
    

    ,如果仍不起作用,请尝试将方法::post添加到表单中,然后重试。

        3
  •  0
  •   Wasif Hossain    8 年前

    您的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 . 有效方式可能如下所示:

    @用户。技能。推送(Skill.new(Skill:params[:Skill]))

    • build(attributes = {}, &block) :返回已用实例化的集合类型的新对象 attributes 并链接到此对象,但尚未保存。如果使用这种方法,那么 respond_to block会更有意义,因为用户技能在你打电话之前不会被保存 @user.save .
        4
  •  0
  •   Diego Patricio Aguilef Sánchez    8 年前

    首先,更换 ajax:success ajax:complete 在eventListener中

    您应该添加 remote: true 然后,在表单html参数中,您的请求将以您想要的格式响应(默认值应为“JS”)

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

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

    最终与 send_data ,您可以将数据发送到Ajax回调