3

シンプルな Ember.js アプリケーションを Grape API バックエンドに何時間も投稿しようとしてきましたが、うまくいかないようです。Swagger のドキュメントを介して API に新しいレコードを投稿できるため、API が機能することはわかっています。それらは永続化されています。サーバーからすべてのレコードを取得してページ上で操作できるため、API と Ember が問題なく通信していることはわかっています。また、レコードがローカル ストレージに保持されているため、Ember が真空状態で正常に動作していることもわかっています。

ただし、POST リクエストを機能させることができないようです。常に 400 が返されます。Rack-Cors を適切に構成し、フロントエンドに ActiveModelAdapter を、バックエンドに ActiveModelSerializer をすべて設定しました。

モデルはこちら

Contact = DS.Model.extend {
  firstName: DS.attr('string'),
  lastName:  DS.attr('string'),
  email:     DS.attr('string'),
  title:     DS.attr('string'),
  createdAt: DS.attr('date'),
  updatedAt: DS.attr('date')
}

およびコントローラー

ContactsNewController = Ember.ObjectController.extend(
  actions:
    save: ->
      @get('model').save()
    cancel: ->
      true
)

APIの関連部分は次のようになります

desc 'Post a contact'
  params do
    requires :first_name, type: String, desc: 'First name of contact'
    requires :last_name , type: String, desc: 'Last name of the contact'
    requires :email     , type: String, desc: 'Email of the contact'
    requires :title     , type: String, desc: 'Title of the contact'
  end
  post do
    Contact.create!(
      first_name: params[:first_name],
      last_name:  params[:last_name],
      email:      params[:email],
      title:      params[:title]
    )
  end

私が使用しているフォームは...

<form {{action 'save' on='submit'}}>
  <h2>{{errorMessage}}</h2>

  <label>First Name</label>
  {{input value=firstName placeholder='First Name' type='text' autofocus=true}}

  <label>Last Name</label>
  {{input value=lastName placeholder='Last Name' type='text'}}

  <label>Email</label>
  {{input value=email placeholder='Email' type='text'}}

  <label>Job Title</label>
  {{input value=title placeholder='Job Title' type='text'}}

  <hr>

  <input type='submit' value='Save'>
</form>

そして、私が得る応答は...

{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}

テイカーはいますか?申し訳ありませんが、私はこれが初めてです。何かがバインドされていませんが、その理由はわかりません。


アップデート

さらに調査...

IMAGE: API cURL への POST リクエスト (Postman 経由) は正常に機能します。.

ただし、Ember から POST すると、サーバーの応答は引き続き

{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}

IMAGE: Chrome Dev Tools からの POST リクエストの出力は次のようになります

また、コントローラーを...に変更しました。これにより、上記のchrome dev toolsログに出力が表示されます。

`import Ember from 'ember'`

ContactsNewController = Ember.ObjectController.extend(
  actions:
    createContact: ->
      firstName = @get('firstName')
      lastName  = @get('lastName')
      email     = @get('email')
      title     = @get('title')

    newRecord = @store.createRecord('contact', {
                   firstName: firstName,
                   lastName:  lastName,
                   email:     email,
                   title:     title
                 })

    self = this

    transitionToContact = (contact) ->
      self.transitionToRoute('contacts.show', contact)

    newRecord.save().then(transitionToContact)
   )

`export default ContactsNewController`
4

2 に答える 2

5

私は Ember.js についてまったく何も知りませんが、しばらくの間、Grape を使用して API を構築してきたので、お手伝いできると思います。添付した画像を見ると、Ember.js がペイロード内に間違った JSON を作成しており、Grape API はそのようにフォーマットされた JSON を想定していないようです。2 番目の画像でわかるように、次のような JSON を作成しています。

{ contact: {...} }

ただし、API は次のような JSON 形式を想定しています。

{ first_name: "" ... }

さて、Chrome 開発ツールを介して同じリクエストを送信する方法を見てください...「フォームデータ」オプションを使用して本文リクエストを作成しているため、この特定のケースでは機能しています。それを「raw」に変更して、間違った JSON を上に置くと、Ember.Js を使用した場合と同じエラーが発生します。

私は Ember.Js を支援する専門知識を持っていないため、具体的な解決策はありません... しかし、Amber.js アプリケーションで、次のような JSON 要求を作成する方法で何かを変更する必要があります。

{ first_name: "", last_name: "", email: "" }

それ以外の:

{ contact: { first_name: "" ... } }

それがあなたを助けることを願っています!

アップデート

問題の別の解決策は、Grape API を変更することです。この場合、次のように、 paramsブロック内にグループブロックを作成する必要があります(連絡先フィールドが params[:contact] ハッシュ内に格納されていることを考慮してください)。

desc 'Post a contact'
params do
    group :contact, type: Hash do
        requires :first_name, type: String, desc: 'First name of contact'
        requires :last_name , type: String, desc: 'Last name of the contact'
        requires :email     , type: String, desc: 'Email of the contact'
        requires :title     , type: String, desc: 'Title of the contact'
    end
end
post do
    Contact.create!(
        first_name: params[:contact][:first_name],
        last_name:  params[:contact][:last_name],
        email:      params[:contact][:email],
        title:      params[:contact][:title]
    )
end
于 2014-11-12T19:34:54.797 に答える