如何通过AJAX POST请求关联HABTM关系中的两个对象

时间:2015-11-16 09:51:53

标签: ruby-on-rails ajax has-and-belongs-to-many

我无法将一个对象与HABTM关系中的另一个对象关联,只有在通过JSON POST创建新对象时(关系在使用Rails控制台时按预期工作)。

要重现:我创建了一个包含视频(包含标题和网址)和播放列表(有名称)的示例项目:

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)
  }
});

问题:未使用播放列表_id且生成的视频对象与播放列表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通过白名单?

2 个答案:

答案 0 :(得分:3)

如果这些关联设置正确,则您的播放列表模型应具有video_ids属性,并且您的视频模型应具有playlist_ids属性。

您可以通过表单传递这些内容,rails应该在您的播放列表_视频链接表中创建相应的记录。

因此,在您的 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相关联,例如。

答案 1 :(得分:1)

当您使用habtm时,您将获得几种应该使用的方法:

enter image description here

具体来说,如果您想在创建时设置playlist_id的{​​{1}},那么您最好填充video属性:

playlist_ids

这会覆盖与$.ajax({ url: "http://" + window.location.host + "/videos.json", type:"POST", contentType:"application/json; charset=utf-8", dataType:"json", data: JSON.stringify({"title": title, "url": "http://www.youtube.com", "playlist_ids": [1]}), success: function(msg) { console.log("added " + msg.title) } }); #app/controllers/videos_controllers.rb class VideosController < ApplicationController def create @video = Video.new video_params @video.save end private def video_params params.require(:video).permit(:title, :url, playlist_ids: []) end end 相关联的当前playlists;这意味着如果您想添加 / 删除视频到播放列表,您最好使用video<<方法。

如果需要,我可以解释如何执行此操作。