Rails (バージョン 3.2.9) アプリで REST API を使用しようとしています。
モデル自体の詳細とネストされた子を含む、標準のレール スキャフォールディング コントローラーに json パケットを POST しています。
親モデルとその子がデータベースに正常に挿入されました。ただし、POST からの応答は、ネストされた子を 2 倍にします。
POST 応答でネストされた関連付けが 2 倍になっているのはなぜですか? 私はここ数日間、これを正しくしようとしてきました...それは私を狂わせています。
具体例
JSON リクエスト
POST http://localhost:3000/audio_events HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 432
Accept: application/json, text/plain, */*
{
"audio_event": {
"start_time_seconds": 0.05,
"end_time_seconds": 15.23,
"low_frequency_hertz": 1000,
"high_frequency_hertz": 8753,
"audio_event_tags_attributes": [
{
"tag_id": "-1"
},
{
"tag_id": "-2"
}
],
"audio_recording_id": "1bd0d668-1471-4396-adc3-09ccd8fe949a"
}
}
JSON レスポンス
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
そして、スタンプ可能マクロとacts_as_paranoidマクロを削除しようとしましたが、効果がありませんでした。
アップデート 2
ネストされた属性を 3 つ追加しようとすると、6 つ返されます。4 は 8 を返し、5 は 10 を返します。