仅在通过JSON POST创建新对象时,我无法将HABTM关系中的一个对象与另一个对象关联(该关系在使用Rails控制台时按预期工作)。
要重现:我创建了一个带有视频(具有标题和URL)和播放列表(具有名称)的示例项目:
rails new videotest
cd videotest
rails g scaffold video title:string url:string
rails g scaffold playlist name:string
rails g migration create_playlists_videos playlist_id:integer video_id:integer
rake db:migrate
我在模型之间设置has_and_belongs_to_many关系:
class Playlist < ActiveRecord::Base
has_and_belongs_to_many :videos
end
class Video < ActiveRecord::Base
has_and_belongs_to_many :playlists
end
在视频控制器中,我将playlist_ids参数列入白名单:
def video_params
params.require(:video).permit(:title, :url, playlist_ids: [])
end
然后在Rails控制台中创建一些示例对象:
Video.create!(title:"video1", url:"http://youtube.com/123")
Video.create!(title:"video2", url:"http://youtube.com/456")
@playlist = Playlist.create(name:"playlist1")
@playlist.videos.append([Video.first, Video.second])
Playlist.first.videos.count
返回预期的2,表明HABTM关系已正确配置。
我可以使用AJAX POST请求成功创建一个新的Video对象,在这里我还对第一个播放列表的ID进行了硬编码:
data = JSON.stringify({
"title": "test video",
"url": "http://www.youtube.com/987",
"playlist_ids": [1]
});
$.ajax({
url: "http://" + window.location.host + "/videos.json",
type:"POST",
contentType:"application/json; charset=utf-8",
dataType:"json",
data: data,
success: function(msg) {
console.log("added " + msg.title)
}
});
问题:未使用playlist_id,并且生成的Video对象未与Playlist 1关联。
该create
方法包括:
def create
@video = Video.new(video_params)
我注意到其中video_params
不包含playlist_id,但包含params
:
(byebug) video_params
{"title"=>"test video", "url"=>"http://www.youtube.com/987"}
(byebug) params[:playlist_ids]
[1]
为什么不playlist_ids
通过白名单?
如果这些关联设置正确,则您的播放列表模型应具有video_ids属性,而您的视频模型应具有playlist_ids属性。
您可以通过表单传递这些内容,并且rails应该在playlists_videos链接表中创建相应的记录。
因此,在您的VideosController中,像这样设置您的白名单:
def video_params
params.require(:video).permit(:title, :url, playlist_ids: [])
end
现在调整您的ajax调用,使其像这样通过playlist_ids数组:
JSON.stringify({ "video": {"title": title, "url": "http://www.youtube.com", "playlist_ids": [1,2]}})
记住将参数嵌套在“视频”节点内。
因此,在这种情况下,例如,您要将视频与playlist_id 1和playlist_id 2相关联。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句