Ruby on rails 从json POST返回重复的嵌套关联
我正在尝试在我的rails(3.2.9版)应用程序中使用RESTAPI 我正在将一个json数据包发布到一个标准的rails脚手架控制器,其中包括模型本身的细节和嵌套的子级 父模型及其子模型已成功插入数据库。但是,来自POST的响应将嵌套子级加倍 为什么在POST响应中嵌套的关联会加倍?在过去的几天里,我一直在努力把这件事做好。。。它快把我逼疯了 具体例子 JSON请求 JSON响应 模型 多对多模型Ruby on rails 从json POST返回重复的嵌套关联,ruby-on-rails,activerecord,associations,ruby-on-rails-3.2,has-many-through,Ruby On Rails,Activerecord,Associations,Ruby On Rails 3.2,Has Many Through,我正在尝试在我的rails(3.2.9版)应用程序中使用RESTAPI 我正在将一个json数据包发布到一个标准的rails脚手架控制器,其中包括模型本身的细节和嵌套的子级 父模型及其子模型已成功插入数据库。但是,来自POST的响应将嵌套子级加倍 为什么在POST响应中嵌套的关联会加倍?在过去的几天里,我一直在努力把这件事做好。。。它快把我逼疯了 具体例子 JSON请求 JSON响应 模型 多对多模型 class AudioEventTag < ActiveRecord::Base b
class AudioEventTag < ActiveRecord::Base
belongs_to :audio_event
belongs_to :tag
accepts_nested_attributes_for :audio_event
attr_accessible :audio_event, :tag, :tag_id
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
validates_uniqueness_of :audio_event_id, :scope => :tag_id
end
而且,我试着去掉了口吃和妄想宏,但没有效果
更新2
如果我尝试添加3个嵌套属性,则返回6个。4返回8,5返回10。根据评论重新发布 看起来像是json序列化问题。如果单独的get正在工作,您可以尝试在控制器中的format.json之前重新加载
@audio\u event.audio\u event\u标记
--
这当然很奇怪。音频事件标记的内存详细信息在@audio\u event.save行出错。AudioEvent是否有保存后回调?。如果没有回电,我不知道怎么会这样。我们需要复制它。如果所有嵌套属性都出现这种情况,这将是一个严重的问题。我发布了一个关于一个可以使用̉
作为̉的问题的答案:也许这有助于找出问题所在。今天晚些时候,我将尝试实现您的代码,看看是否能发现发生了什么。我对您的模型进行了快速实现,但似乎没有重复。它按预期工作。也许问题不在于模型,而在于调用模型序列化的方式。你能用这些代码更新你的答案吗?我只是想知道,你有没有试着看看当你注释掉那些结巴的宏并把它们当作偏执的宏时会发生什么?也许他们妨碍了你。两人都在摆弄活动记录的内部结构……我为没有及时回复而道歉——我本来希望收到电子邮件更新(我没有收到)。我在评论中尝试了这两个建议,运气不好。你确定数据库中的audio\u event\u标签没有加倍吗?这似乎是唯一有效的方法。这是一个有点烦人,我必须额外的查询重新加载音频事件标签。。。我不明白为什么要这样。。。至少我可以继续前进。仅供参考@so_mv,AudioEvent和AudioEventTag在保存回调集后都有一个。。。通过调试,after_save prop有一个相同类的数组,其中包含一个项。我试图清除这些阵列,但没有效果。如果您想避免db呼叫,可以尝试@audio\u event.audio\u event\u tags.uniq!{| aet | aet.tag_id}而不是.reload。注意uniq!仅适用于Ruby 1.9.3。v1.8.7也有uniq,但不使用块进行比较。
HTTP/1.1 201 Created
Location: http://localhost:3000/audio_events/27
Content-Type: application/json; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c79ccdf981a9fadad3a8b08c3a878e8e"
Cache-Control: max-age=0, private, must-revalidate
Content-Length: 924
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20)
Date: Mon, 26 Nov 2012 00:27:47 GMT
Connection: Keep-Alive
{
"created_at": "2012-11-26T00:27:32Z",
"creator_id": 1,
"deleted_at": null,
"deleter_id": null,
"end_time_seconds": "15.23",
"high_frequency_hertz": "8753.0",
"id": 27,
"is_reference": false,
"low_frequency_hertz": "1000.0",
"start_time_seconds": "0.05",
"updated_at": "2012-11-26T00:27:32Z",
"updater_id": 1,
"audio_event_tags": [
{
"audio_event_id": 27,
"created_at": "2012-11-26T00:27:32Z",
"creator_id": 1,
"tag_id": -1,
"updated_at": "2012-11-26T00:27:32Z",
"updater_id": 1
},
{
"audio_event_id": 27,
"created_at": "2012-11-26T00:27:32Z",
"creator_id": 1,
"tag_id": -2,
"updated_at": "2012-11-26T00:27:32Z",
"updater_id": 1
},
// DUPLICATES ARE HERE
{
"audio_event_id": 27,
"created_at": "2012-11-26T00:27:32Z",
"creator_id": 1,
"tag_id": -1,
"updated_at": "2012-11-26T00:27:32Z",
"updater_id": 1
},
{
"audio_event_id": 27,
"created_at": "2012-11-26T00:27:32Z",
"creator_id": 1,
"tag_id": -2,
"updated_at": "2012-11-26T00:27:32Z",
"updater_id": 1
}
],
"audio_recording": {
"id": 1,
"uuid": "1bd0d668-1471-4396-adc3-09ccd8fe949a"
}
}
class AudioEventTag < ActiveRecord::Base
belongs_to :audio_event
belongs_to :tag
accepts_nested_attributes_for :audio_event
attr_accessible :audio_event, :tag, :tag_id
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
validates_uniqueness_of :audio_event_id, :scope => :tag_id
end
class Tag < ActiveRecord::Base
has_many :audio_event_tags
has_many :audio_events, :through => :audio_event_tags
accepts_nested_attributes_for :audio_events, :audio_event_tags
attr_accessible :is_taxanomic, :text, :type_of_tag
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
acts_as_paranoid
validates_as_paranoid
end
class AudioEvent < ActiveRecord::Base
belongs_to :audio_recording
has_many :tags, :through => :audio_event_tags, :uniq => true
has_many :audio_event_tags
accepts_nested_attributes_for :audio_event_tags
attr_accessible :audio_recording_id, :end_time_seconds, :high_frequency_hertz, :is_reference,
:low_frequency_hertz, :start_time_seconds,
:tags_attributes, :audio_event_tags_attributes
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
acts_as_paranoid
validates_as_paranoid
# validation
validates :audio_recording, :presence => true
validates :start_time_seconds, :presence => true, :numericality => { :greater_than_or_equal_to => 0 }
validates :end_time_seconds, :numericality => { :greater_than_or_equal_to => 0 }
validates :low_frequency_hertz, :presence => true, :numericality => { :greater_than_or_equal_to => 0 }
validates :high_frequency_hertz, :numericality => { :greater_than_or_equal_to => 0 }
# json formatting
def as_json(options={})
super(
:include =>
[
:audio_event_tags,
:audio_recording => {:only => [:id, :uuid]}
],
:except => :audio_recording_id
)
end
end
# POST /audio_events
# POST /audio_events.json
def create
@audio_event = AudioEvent.new(params[:audio_event])
#@audio_event.audio_event_tags.each{ |aet| aet.build() }
#@audio_event.audio_event_tags.count.times { @audio_event.audio_event_tags.build }
respond_to do |format|
if @audio_event.save
format.json { render json: @audio_event, status: :created, location: @audio_event }
else
format.json { render json: @audio_event.errors, status: :unprocessable_entity }
end
end
end