【问题标题】:AJAX update not passing proper parameters to SQL call in different environmentsAJAX 更新未在不同环境中将正确的参数传递给 SQL 调用
【发布时间】:2017-08-11 15:46:57
【问题描述】:

问题

所以我正在使用 AJAX 来更新具有 namephone 作为属性的组织。该更新在本地运行良好,但不适用于生产。

数据

我在本地得到的日志:

Started PUT "/organizations/14" for ::1 at 2017-08-11 08:03:18 -0700
Processing by OrganizationsController#update as JSON
  Parameters: {"organization"=>{"name"=>"Org Name", "phone"=>"3434234322"}, "id"=>"14"}
  User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 195], ["LIMIT", 1]]
  Organization Load (0.5ms)  SELECT  "organizations".* FROM "organizations" WHERE "organizations"."user_id" = 195 LIMIT $1  [["LIMIT", 1]]
   (0.2ms)  BEGIN
  SQL (9.2ms)  UPDATE "organizations" SET "phone" = $1, "updated_at" = $2 WHERE "organizations"."id" = $3  [["phone", "3434234322"], ["updated_at", 2017-08-11 15:03:18 UTC], ["id", 14]]
   (0.5ms)  COMMIT
Completed 200 OK in 21ms (Views: 0.8ms | ActiveRecord: 11.0ms)

我在生产中获得的日志:

Started PUT "/organizations/1" for [censored] at 2017-08-11 15:12:58 +0000 
Processing by OrganizationsController#update as JSON 
  Parameters: {"organization"=>{"name"=>"Org Name", "phone"=>"12121212"}, "id"=>"1"} 
  User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 48], ["LIMIT", 1]] 
  Organization Load (0.9ms)  SELECT  "organizations".* FROM "organizations" WHERE "organizations"."user_id" = 48 LIMIT $1  [["LIMIT", 1]] 
   (0.6ms)  BEGIN 
  SQL (0.9ms)  UPDATE "organizations" SET "updated_at" = $1 WHERE "organizations"."id" = $2  [["updated_at", 2017-08-11 15:12:58 UTC], ["id", 1]] 
   (1.7ms)  COMMIT 
Completed 200 OK in 12ms (Views: 0.6ms | ActiveRecord: 4.9ms) 

我的想法

所以这里的区别似乎是 SQL 调用(第 7 行)。在本地,电话正确传入,如下所示:

SQL (9.2ms) UPDATE "organizations" SET "phone" = $1, "updated_at" = $2 WHERE "organizations"."id" = $3 [["phone", "3434234322"], ["updated_at", 2017-08-11 15:03:18 UTC], ["id", 14]]

但在生产中,它不是......

SQL (0.9ms) UPDATE "organizations" SET "updated_at" = $1 WHERE "organizations"."id" = $2 [["updated_at", 2017-08-11 15:12:58 UTC], ["id", 1]]

我不明白为什么这会在本地工作,但不能在生产环境中工作。还值得注意的是,如果我对name 进行 AJAX 更新,它在两种环境中都可以使用。我最近在数据库中添加了phone,而这个特定的组织在创建时没有phone 作为属性,所以我认为这可能与它有关。但是我可以在数据库中看到该属性,并且可以为其赋值并保存而不会出现任何问题。除非我弄错了,否则当我将它传递给控制器​​时,这正是我想要做的。

相关代码

我的 AJAX 调用:

$.ajax({
    url: `/organizations/${organization.id}`,
    method: 'PUT',
    data: { "organization": {
        "name": nameValue,
        "phone": phoneValue
    }},
    dataType: 'json',
    success: (data) => {
        // do stuff
    }
});

还有我的控制器(Rails):

class OrganizationsController < ApplicationController
    before_action :set_organization, only: [:edit, :update]
    skip_before_action :verify_authenticity_token

    def edit
    end

    def update
        respond_to do |format|
            if @organization.update(organization_params)
                format.html { redirect_to '/dashboard', notice: 'Organization was successfully updated.' }
                format.json { render json: @organization }
            else
                format.html { render '/dashboard' }
                format.json { render json: @organization.errors, status: :unprocessable_entity }
            end
        end
    end

    private
    def set_organization
        @organization = Organization.find_by(user: current_user)
    end

    def organization_params
        params.require(:organization).permit(:name, :phone)
    end

end

我只添加了上面的 AJAX 调用,因为我确信这就是所有需要的。但为了完整起见,这里更多的是它使用的 React 组件:

import React from 'react';

export default class OrganizationInput extends React.Component{

    constructor(props) {
        super(props);
        this.state = {
            nameValue: this.props.organization.name,
            phoneValue: this.props.organization.phone,
            xhr: false,
            faClass: null,
        }
    }

    handleInput =(event, input)=> {
        this.setState({[input]: event.target.value

            // creates font awesome spinner
            this.handleFaChange() 

            const { organization } = this.props
            const { nameValue, phoneValue } = this.state

            if(this.state.xhr !== false) {clearTimeout(this.state.xhr)}

            this.state.xhr = setTimeout(() => {
                $.ajax({
                    url: `/organizations/${organization.id}`,
                    method: 'PUT',
                    data: { "organization": {
                        "name": nameValue,
                        "phone": phoneValue
                    }},
                    dataType: 'json',
                    success: (data) => {
                        this.setState({xhr: false})

                        // creates font awesome check mark
                        this.handleFaChange()
                    }
                });
            }, 300)
        })
    }

    render() {
        const { organization } = this.props
        return (
            <div>
                <input value={this.state.nameValue} className="organization-input" placeholder={`Barbershop Name`} onChange={(e)=> {this.handleInput(e, "nameValue")}}/>
                <input value={this.state.phoneValue} className="organization-input" placeholder={`Phone Number`} onChange={(e)=> {this.handleInput(e, "phoneValue")}}/>
            </div>
        );
    }
}

【问题讨论】:

    标签: ruby-on-rails ajax postgresql reactjs http


    【解决方案1】:

    phone 属性添加到organizations 表后,应用程序是否重新启动?

    此外,您可能希望将 if @organization.update(organization_params) 更改为 if @organization.update!(organization_params),以便在验证失败时引发异常。

    【讨论】:

    • 是的,它已重新启动。什么都没做。感谢您提供有关更新电话的提示。不过,我确实想出了一个解决方案(有点)。根本不会更新在添加电话属性及其相应迁移之前创建的任何组织。我刚刚编写了一个快速脚本来克隆以前在数据库中的所有组织,并将所有关联重新分配给这些组织。这是为我解决问题的解决方法,但我仍然很好奇为什么我必须这样做。我可以从控制台更新组织,但不能直接从应用程序更新。
    • 就好像正在运行的应用程序不知何故没有看到那个新字段......但即使这不应该是问题,因为你重新启动它。这肯定是个谜。
    猜你喜欢
    • 1970-01-01
    • 2012-01-15
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多