【问题标题】:Angular 4 & Rails 5 Post Request JSON FormattingAngular 4 和 Rails 5 发布请求 JSON 格式
【发布时间】:2017-04-18 21:26:31
【问题描述】:

我正在使用 Rails 后端开发 Angular 应用程序。我在格式化参数哈希时遇到问题,以便 rails 可以使用它。数据是多对多关系,表单包含嵌套属性。在 Rails 中,我的模型使用 accepts_nested_attributes_for 助手。我确切地知道 rails 所期望的格式,但是当我提出POST 请求时,有一个小细节是关闭的。我将在下面列出两个参数哈希。一个是 Angular 产生的,另一个是 Rails 期望的。

关于 Angular 请求的问题在于 rails 期望在 expense_expense_categories 属性中嵌套更深一层。我从来不明白为什么rails需要它。角度产生的东西对我来说是合乎逻辑的。我的问题是.. 我需要做什么来格式化 Angular 中的参数?看看我目前所拥有的,我这样做的方式是否满足 Angular 最佳实践?

角度:

{
    "expense": {
        "date": "2017/4/13",
        "check_number": "132",
        "debit": "0",
        "notes": "har",
        "amount": "24",
        "payee_id": "334"
    },
    "expense_expense_categories_attributes": [{
            "expense_category_id": "59",
            "amount": 12
        },
        {
            "expense_category_id": "62",
            "amount": 11
        }
    ]
}

Rails 的期望:

{
    "expense": {
        "date": "2017/12/12",
        "check_number": "122",
        "debit": "0",
        "notes": "har",
        "amount": "24",
        "payee_id": "334",
        "expense_expense_categories_attributes": {
            "210212312": {
                "expense_category_id": "72",
                "amount": "12"
            },
            "432323432": {
                "expense_category_id": "73",
                "amount": "12"
            }
        }
    }
}

我的角度代码如下。

onSubmit() 组件中的方法:

onSubmit() {
    this.expenseService.addExpense(this.expenseForm.value)
      .subscribe(
        () => {
          this.errorMessage = '';
        },
        error =>  {
          this.errorMessage = <any>error;
        }
      );
    this.expenseForm.reset();
  }

在我的服务文件中添加费用:

addExpense(expense: Expense): Observable<any> {
  let headers = new Headers({'Content-Type': 'application/json'});
  let options = new RequestOptions({headers: headers});

  return this.http.post('http://localhost:3000/expenses', expense, options)
    .map(
      (res: Response) => {
        const expenseNew: Expense = res.json();
        this.expenses.push(expenseNew);
        this.expensesChanged.next(this.expenses.slice());
      })
    .catch(this.handleError);
}

我的主要形式:

private initForm() {
    let expense_expense_categories_attributes = new FormArray([]);
    this.expenseForm = this.fb.group({
      id: '',
      date: '',
      amount: '',
      check_number: '',
      debit: '',
      payee_id: '',
      notes: '',
      expense_expense_categories_attributes: expense_expense_categories_attributes
    });
  }

嵌套属性的我的 FormArray:

onAddExpenseCategories() {

(<FormArray>this.expenseForm.get('expense_expense_categories_attributes')).push(
      new FormGroup({
        'expense_category_id': new FormControl(null, Validators.required),
        'amount': new FormControl(null, [
          Validators.required
        ])
      })
    );
  }

更新:我能够让它工作,但我不得不使用一个糟糕的正则表达式来操纵我想要的请求。这是一个非常丑陋的选择,所以我仍然需要找到更好的选择。有没有更好的方法来格式化 JSON 对象并替换内容?我不确定正确的方法。需要帮助。

【问题讨论】:

  • 您是否尝试过将wrap_parameters 用于:jsonapi.rubyonrails.org/classes/ActionController/ParamsWrapper.html
  • @Jon 似乎在 API 模式下使用 Rails 默认启用
  • 是的,但默认情况下它只会包装模型本身的属性。如果您要传递其他属性,例如 expense_categories_attributes,则需要将这些属性显式添加到包装参数中。
  • 好的。我懂了。因此,如果我执行wrap_parameters :expense, include: [:expense_expense_categories] 之类的操作,它应该可以工作吗?
  • 试一试——如果不进行测试,我无法确定。作为参考,这里有一个关于这个问题的未解决问题 - github.com/rails/rails/issues/17216

标签: ruby-on-rails angular typescript rails-api


【解决方案1】:

您需要像这样将expense_expense_categories 添加到wrap_parameters

wrap_parameters :expense, include: [:expense_expense_categories_attributes]

其他属性必须显式添加到wrap_parameters,因为它默认只包装模型本身的属性。

【讨论】:

  • 我还必须在 include: 数组中列出我的所有费用属性。我想它会默认这样做。这就是为什么乔恩上面的评论不起作用的原因。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-12-31
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 2018-11-22
  • 2018-11-07
相关资源
最近更新 更多