Bot*_*oke 3 ruby-on-rails ruby-grape ember.js ruby-on-rails-4 grape-api
我一直试图让一个简单的Ember.js应用程序现在发布到Grape API后端几个小时,但我似乎无法让它工作.我知道API有效,因为我可以通过Swagger文档向它发布新记录,并且它们是持久的.我知道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')
}
Run Code Online (Sandbox Code Playgroud)
和控制器
ContactsNewController = Ember.ObjectController.extend(
actions:
save: ->
@get('model').save()
cancel: ->
true
)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我正在使用的表格是......
<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>
Run Code Online (Sandbox Code Playgroud)
我得到的回应是......
{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}
Run Code Online (Sandbox Code Playgroud)
任何接受者?对不起,我是新来的.有些事情没有受到约束,但我不知道为什么.
更多调查......
IMAGE:对API cURL的POST请求(通过Postman)工作正常..
但是,当我从Ember POST时,服务器响应仍然存在
{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}
Run Code Online (Sandbox Code Playgroud)
IMAGE:来自Chrome开发工具的POST请求的输出如下所示
我还将控制器更改为...,它在上面的chrome dev工具日志中给出了输出.
`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`
Run Code Online (Sandbox Code Playgroud)
我对Ember.js一无所知,但我一直在使用Grape构建API一段时间,所以我想我可以帮助你.查看您附加的图像,似乎Ember.js在Payload中创建了一个不正确的JSON,而您的Grape API并不期望以这种方式形成JSON格式.正如你在第二张图片中看到的,它正在创建一个这样的JSON:
{ contact: {...} }
Run Code Online (Sandbox Code Playgroud)
但是,您的API期望像这样的JSON格式:
{ first_name: "" ... }
Run Code Online (Sandbox Code Playgroud)
现在,看看您是如何通过Chrome开发工具发送相同的请求...您正在使用"表单数据"选项来创建正文请求,这就是为什么在这种特定情况下它正在工作.尝试将其更改为"raw"并将不正确的JSON置于上方,您将获得使用Ember.Js时遇到的相同错误.
我没有具体的解决方案,因为我没有专业知识来帮助你使用Ember.Js ......但是你必须改变你的Amber.js应用程序中的某些东西,它会创建一个像这样的JSON请求:
{ first_name: "", last_name: "", email: "" }
Run Code Online (Sandbox Code Playgroud)
代替:
{ contact: { first_name: "" ... } }
Run Code Online (Sandbox Code Playgroud)
希望它能帮到你!
UPDATE
您问题的另一个解决方案是更改Grape API.在这种情况下,您必须在params块中创建一个组块,如下所示(考虑到联系人字段现在存储在params [:contact] Hash中):
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
Run Code Online (Sandbox Code Playgroud)