RTP*_*mad 12 json ruby-on-rails nested-attributes ruby-on-rails-3 ruby-on-rails-4
我已经搜索了相关的问题,但仍然有问题从我的AngularJS前端返回的rails 4到JSON中更新嵌套属性.
问题:下面的代码概述了从我的Rails4应用程序中从AngularJS传递到Candidate模型的JSON.Candidate模型有很多Works,我试图通过Candidate模型更新Works模型.由于某种原因,Works模型无法更新,我希望有人可以指出我缺少的东西.谢谢你的帮助.
这是候选人AngularJS前端的json:
{"id"=>"13", "nickname"=>"New Candidate", "works_attributes"=>[
{"title"=>"Financial Analyst", "description"=>"I did things"},
{"title"=>"Accountant", "description"=>"I did more things"}]}
Run Code Online (Sandbox Code Playgroud)
然后,Rails通过添加候选标头将此JSON转换为以下内容,但不包括候选标头下的嵌套属性,并且无法通过候选模型更新works_attributes:
{"id"=>"13", "nickname"=>"New Candidate", "works_attributes"=>[
{"title"=>"Financial Analyst", "description"=>"I did things"},
{"title"=>"Accountant", "description"=>"I did more things"}],
"candidate"=>{"id"=>"13", "nickname"=>"New Candidate"}}
Run Code Online (Sandbox Code Playgroud)
candidate_controller.rb包含一个简单的更新:
class CandidatesController < ApplicationController
before_filter :authenticate_user!
respond_to :json
def update
respond_with Candidate.update(params[:id], candidate_params)
end
private
def candidate_params
params.require(:candidate).permit(:nickname,
works_attributes: [:id, :title, :description])
end
end
Run Code Online (Sandbox Code Playgroud)
candidate.rb模型包含以下代码,用于定义与工作模型的has_many关系:
class Candidate < ActiveRecord::Base
## Model Relationships
belongs_to :users
has_many :works, :dependent => :destroy
## Nested model attributes
accepts_nested_attributes_for :works, allow_destroy: true
## Validations
validates_presence_of :nickname
validates_uniqueness_of :user_id
end
Run Code Online (Sandbox Code Playgroud)
最后,works.rb模型定义了has_many关系的另一面:
class Work < ActiveRecord::Base
belongs_to :candidate
end
Run Code Online (Sandbox Code Playgroud)
我感谢你提供的任何帮助,因为我确信我错过了一些相当简单的东西.
谢谢!
我也一直在使用Rails和AngularJS之间的JSON API.我使用与RTPnomad相同的解决方案,但找到了一种不必硬编码include属性的方法:
class CandidatesController < ApplicationController
respond_to :json
nested_attributes_names = Candidate.nested_attributes_options.keys.map do |key|
key.to_s.concat('_attributes').to_sym
end
wrap_parameters include: Candidate.attribute_names + nested_attributes_names,
format: :json
# ...
end
Run Code Online (Sandbox Code Playgroud)
请参阅Rails中的这个问题,看看他们是否/何时解决了这个问题.
更新10/17
等待公关合并:rail/rails#19254.
我想出了一种基于rails文档来解决我的问题的方法:http://edgeapi.rubyonrails.org/classes/ActionController/ParamsWrapper.html
基本上,Rails ParamsWrapper默认启用从前端包装JSON,并在Rails中使用根元素,因为AngularJS不会在根包装元素中返回数据.以上文档包含以下内容:
"在没有:include或:exclude选项集的ActiveRecord模型中,它只会包装类方法attribute_names返回的参数."
这意味着我必须使用以下语句显式包含嵌套属性,以确保Rails包含所有元素:
class CandidatesController < ApplicationController
before_filter :authenticate_user!
respond_to :json
wrap_parameters include: [:id, :nickname, :works_attributes]
...
Run Code Online (Sandbox Code Playgroud)
如果有更好的方法在AngularJS和Rails之间传递JSON数据,请为此问题添加另一个答案
| 归档时间: |
|
| 查看次数: |
3190 次 |
| 最近记录: |