Ember 和 Rails has_many 关系
Ember and Rails has_many relationship
我有两个模型,Project 和 Image,它们具有 has_many 关系(项目有很多图像)。我在前端使用 Rails 作为 API 和 Ember。
我遇到的问题是无法将图像数据传递给 ember。
我有以下设置:
Rails结束
app/models/image.rb
class Image < ActiveRecord::Base
belongs_to :project
mount_uploader :project_image, ImageUploader
end
app/models/project.rb
class Project < ActiveRecord::Base
has_many :images, :dependent => :destroy
accepts_nested_attributes_for :images, allow_destroy: true
end
app/serializers/image_serializer.rb
class ImageSerializer < ActiveModel::Serializer
attributes :project_image, :project_id
end
app/serializers/project_serializer.rb
class ProjectSerializer < ActiveModel::Serializer
attributes :id, :client, :tags, :description, :start_date, :end_date
has_many :images
end
Ember结束
app/assets/javascripts/store.js
DS.RESTAdapter.reopen({
namespace: 'api/v1'
})
App.Store = DS.Store.extend({});
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({});
app/assets/javascripts/routes/projects.js
App.ProjectsRoute = Ember.Route.extend({
model: function() {
return this.store.find('project')
}
})
App.ProjectRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('project', params.project_id)
}
})
app/assets/javascripts/models/project.js
App.Project = DS.Model.extend({
client: DS.attr('string'),
tags: DS.attr('string'),
description: DS.attr('string'),
start_date: DS.attr('string'),
end_date: DS.attr('string'),
images: DS.hasMany('image', {async: true})
});
app/assets/javascripts/models/image.js
App.Image = DS.Model.extend({
project_image: DS.attr('string'),
project_id: DS.attr(),
project: DS.belongsTo('project')
});
当我访问 localhost:3000/api/v1/projects.json 时,我从这里得到的 JSON 输出是
{
"project":
{
"id":8,
"client":"example client",
"tags":"example tag",
"description":"some description",
"start_date":"April 13",
"end_date":"June 13",
"images":[
{
"project_image":
{
"project_image":{"url":"/uploads/image/project_image/6/logo.jpg"}
},
"project_id":8
}
]
}
}
我很确定 ember 的格式是错误的,因为图像数据没有进入 chrome ember 检查器(项目数据工作正常,除了没有图片)。
如果有人知道我哪里出了问题,将不胜感激!
您的输出 JSON 可以采用以下格式:
{
"project": {
"id": 8,
"client": "escapethecity",
"tags": "Wireframing, UI Design",
"description": "",
"start_date": "April 13",
"end_date": "June 13",
"images": [1],
},
"project_image": {
"id": 1,
"url": "/uploads/image/project_image/6/Eagle_logo_v7_no_tail.jpg",
"project_id": 8
}
}
所以,首先你需要指定图像的id
。然后,您可以按照在 project
属性 ("images": [1]
) 和单独的 project_image
中获得 id
数组的方式重组代码] 属性 project
.
中引用的所有项目图像
此外,如果您在一个请求中提供所有信息,则无需在关系中声明 async: true
。
希望对您有所帮助:)
请注意,这是选项之一。您还可以查看 DS.ActiveModelSerializer
; here's a nice explanation.
编辑:
我对序列化器的尝试(虽然只是干写,但可能会打错!):
export default DS.RESTSerializer.extend({
normalizePayload: function(payload) {
// transform the project image
payload.project_image = payload.project.images.map(function(image) {
return {
id: 1, // fake one!
url: image.project_image.project_image.url,
project_id: image.project_id,
project: image.project_id
};
});
// create project images ids (from the fake ones now...)
payload.project.images = payload.project_image.map(function(image) {
return image.id;
});
}
});
我有两个模型,Project 和 Image,它们具有 has_many 关系(项目有很多图像)。我在前端使用 Rails 作为 API 和 Ember。
我遇到的问题是无法将图像数据传递给 ember。
我有以下设置:
Rails结束
app/models/image.rb
class Image < ActiveRecord::Base
belongs_to :project
mount_uploader :project_image, ImageUploader
end
app/models/project.rb
class Project < ActiveRecord::Base
has_many :images, :dependent => :destroy
accepts_nested_attributes_for :images, allow_destroy: true
end
app/serializers/image_serializer.rb
class ImageSerializer < ActiveModel::Serializer
attributes :project_image, :project_id
end
app/serializers/project_serializer.rb
class ProjectSerializer < ActiveModel::Serializer
attributes :id, :client, :tags, :description, :start_date, :end_date
has_many :images
end
Ember结束
app/assets/javascripts/store.js
DS.RESTAdapter.reopen({
namespace: 'api/v1'
})
App.Store = DS.Store.extend({});
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({});
app/assets/javascripts/routes/projects.js
App.ProjectsRoute = Ember.Route.extend({
model: function() {
return this.store.find('project')
}
})
App.ProjectRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('project', params.project_id)
}
})
app/assets/javascripts/models/project.js
App.Project = DS.Model.extend({
client: DS.attr('string'),
tags: DS.attr('string'),
description: DS.attr('string'),
start_date: DS.attr('string'),
end_date: DS.attr('string'),
images: DS.hasMany('image', {async: true})
});
app/assets/javascripts/models/image.js
App.Image = DS.Model.extend({
project_image: DS.attr('string'),
project_id: DS.attr(),
project: DS.belongsTo('project')
});
当我访问 localhost:3000/api/v1/projects.json 时,我从这里得到的 JSON 输出是
{
"project":
{
"id":8,
"client":"example client",
"tags":"example tag",
"description":"some description",
"start_date":"April 13",
"end_date":"June 13",
"images":[
{
"project_image":
{
"project_image":{"url":"/uploads/image/project_image/6/logo.jpg"}
},
"project_id":8
}
]
}
}
我很确定 ember 的格式是错误的,因为图像数据没有进入 chrome ember 检查器(项目数据工作正常,除了没有图片)。
如果有人知道我哪里出了问题,将不胜感激!
您的输出 JSON 可以采用以下格式:
{
"project": {
"id": 8,
"client": "escapethecity",
"tags": "Wireframing, UI Design",
"description": "",
"start_date": "April 13",
"end_date": "June 13",
"images": [1],
},
"project_image": {
"id": 1,
"url": "/uploads/image/project_image/6/Eagle_logo_v7_no_tail.jpg",
"project_id": 8
}
}
所以,首先你需要指定图像的id
。然后,您可以按照在 project
属性 ("images": [1]
) 和单独的 project_image
中获得 id
数组的方式重组代码] 属性 project
.
此外,如果您在一个请求中提供所有信息,则无需在关系中声明 async: true
。
希望对您有所帮助:)
请注意,这是选项之一。您还可以查看 DS.ActiveModelSerializer
; here's a nice explanation.
编辑:
我对序列化器的尝试(虽然只是干写,但可能会打错!):
export default DS.RESTSerializer.extend({
normalizePayload: function(payload) {
// transform the project image
payload.project_image = payload.project.images.map(function(image) {
return {
id: 1, // fake one!
url: image.project_image.project_image.url,
project_id: image.project_id,
project: image.project_id
};
});
// create project images ids (from the fake ones now...)
payload.project.images = payload.project_image.map(function(image) {
return image.id;
});
}
});