【问题标题】:Rails account_params missing parameters from backbone `.save()`Rails account_params缺少主干`.save()`中的参数
【发布时间】:2014-10-06 09:00:58
【问题描述】:

我正在尝试使用 Backbone 1.1.2 和 Rails 4.2.beta1 创建一个用户帐户。

我在骨干中打电话:

public create(){
    var email:string = $('#create-account-email').val(), password:string = $('#create-account-password').val(), passconf:string = $('#create-account-password-confirm').val();
    this.model.set({email: email, password: password, password_confirmation: passconf});
    this.model.save(null, {success: this.success, error: this.error});
}

使用以下请求参数在我的 web 服务中正确调用 rails create 方法:

{"email":"test@test.com","password":"123456","password_confirmation":"123456"}

它正在通过过滤方法

def account_params
  #breakpoint
  params.require(:account).permit(:password, :password_confirmation, :email)
end

但如果我在上述位置放置断点并检查 params 对象,我会得到:

{"email"=>"test@test.com", 
 "password"=>"123456", 
 "password_confirmation"=>"123456", 
 "controller"=>"accounts", 
 "action"=>"create", 
 "account"=>{"email"=>"test@test.com"}, 
 "format"=>"json"}

乍一看,这对我来说是正确的。但是账号创建失败,因为密码是nil

如果检查account_params 的结果,我只会得到:

{"email" => "test@test.com")

为什么密码不包含在帐户参数对象中。我正在使用所有带有rails的默认支架代码和Backbone的默认配置。

【问题讨论】:

  • 您可以张贴您的表格吗?
  • @Mandeep 我为你编辑了上面的代码。这是一个表格,但我正在使用 $().val() 从表格中读取它,所以我为您提供了该代码。
  • 啊好吧,你如何将这些参数发送到服务器?查看您的参数哈希,它们似乎没有正确嵌套
  • @Mandeep 我目前只是让骨干做这件事。我是否需要修改主干发送参数的方式。我的理解是骨干网 + rails 只是工作
  • 不,它们不能开箱即用地一起工作。 Backbone 想发送{p1:v1, p2:v2},但Rails 想看到{model_name: {p1:v1, p2:v2}}。有一些宝石可以帮助将事物粘合在一起,或者您可以自行整理 sync 覆盖。搜索“backbone-rails”。

标签: ruby-on-rails backbone.js typescript backbone-model ruby-on-rails-4.2


【解决方案1】:

我找到了一个 GitHub 存储库,用于 ruby​​ gem backbone-rails,并使用了它们包含的同步覆盖 here

Backbone._sync = Backbone.sync;
Backbone.sync = function (method:string, model:Backbone.Model, options?: any){
    if(options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
        options.contentType = 'application/json';
        var data:any = JSON.stringify(options.attrs || model.toJSON(options));
        if(model.paramRoot) {
            data = {};
            data[model.paramRoot] = model.toJSON(options);
        } else {
            data = model.toJSON();
        }
        options.data = JSON.stringify(data);
    }
    return Backbone._sync(method, model, options);
}

我删除了一些我不需要的项目,但这会将主干属性包装到一个对象中,并以它需要的格式将其发送到 rails 应用程序。

所以参数:

{"email":"test@test.com",
 "password":"123456",
 "password_confirmation":"123456"}

变成:

{"account":
    {"email":"test@test.com",
     "password":"123456",
     "password_confirmation":"123456"}
}

这并非没有对主干应用程序代码进行一点修改...

当我使用打字稿时,我必须使用以下签名将_sync() 方法添加到backbone.d.ts 文件中。

declare module Backbone {

    function _sync(method: string, model: Model, options?: JQueryAjaxSettings):any;

    ...
}

我还需要将以下内容添加到Backbone.Model

class Model extends ModelBase implements OptionalDefaults {

    paramRoot: string;

    ...
}

然后我将paramRoot 属性添加到我的模型中:

export class Account extends Backbone.Model {
    public urlRoot: string;
    public validation:any;
    public paramRoot:string;
    constructor(attributes?: any, options?: any){
        this.paramRoot = 'account';
        this.urlRoot = 'http://mydomain.fake/accounts';
        this.validation = {
            email: {
                required: true,
                pattern: 'email'
            },
            password: {
                required: true,
                minLength: 6
            }
        };
        super(attributes, options);
    }
}

还有其他方法可以让_sync() 方法和paramRoot 属性在不修改backbone.d.ts 文件的情况下传递编译器错误,而是扩展对象并将其添加到另一个.d.ts 文件中。但这对我来说没问题,因为我计划在未来的项目中使用它,我不介意稍微修改 .d.ts 文件。

希望这对将来的人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多