我目前有一个专辑/艺术家数据库,它使用多个联接表来表示艺术家与专辑的关系。它们可以列为Composer,Arranger或Performer。那就是:
class Artist < ActiveRecord::Base
...
has_and_belongs_to_many :albumbycomposers, :class_name => "Album", :join_table => "albums_composers"
has_and_belongs_to_many :albumbyarrangers, :class_name => "Album", :join_table => "albums_arrangers"
has_and_belongs_to_many :albumbyperformers, :class_name => "Album", :join_table => "albums_performers"
...
end
并且
class Album < ActiveRecord::Base
has_and_belongs_to_many :composers, :class_name => "Artist", :join_table => "albums_composers"
has_and_belongs_to_many :arrangers, :class_name => "Artist", :join_table => "albums_arrangers"
has_and_belongs_to_many :performers, :class_name => "Artist", :join_table => "albums_performers"
...
end
此代码用于查找数据库中的现有艺术家,然后创建关联。如果没有艺术家存在,那么我使用.build方法创建艺术家。
class AlbumsController < ApplicationController
...
def create
@album = Album.new(params[:album])
params["Composer Names"].each do |each|
if each.empty? == false
@exists = Artist.find_by_name(each)
if @exists.nil? == true
@album.composers.build(:name => each)
else
@album.composers << Artist.find_by_name(each)
end
end
end
params["Arranger Names"].each do |each|
if each.empty? == false
@exists = Artist.find_by_name(each)
if @exists.nil? == true
@album.arrangers.build(:name => each)
else
@album.arrangers << Artist.find_by_name(each)
end
end
end
...
end
...
end
当我尝试将新艺术家作为作曲家和编曲者进入时,我遇到的问题就出现了。例如,假设我将其作为帖子请求提交
Parameters: {"Name"=>["New Album"],
"Performer Names"=>["New Artist"],
"Composer Names"=>["New Artist"],
"Arranger Names"=>["New Artist"],
...
}
由于作曲家参数是第一个,因此rails会正确解释它们(好像艺术家不存在)。编曲和执行者参数也被解释为艺术家不存在。然后rails开始将数据插入我的数据库。首先创建相册并将其插入相册表中,然后创建“New Artist”并将其插入album_composer(根据.build方法)。
但是,对于编曲器和执行者参数,由于已创建艺术家,因此无法再使用构建方法,因此代码无法正确执行。
我试图通过在这个特定情况下使用编排器和执行者参数行中的push方法(又名&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;作曲家参数,导致“艺术家无法找到”错误。供参考:
collection<<(object, …)
Adds one or more objects to the collection by creating associations in the join table (collection.push and collection.concat are aliases to this method).
Note that this operation instantly fires update sql without waiting for the save or update call on the parent object.
处理此问题的正确方法是什么?
答案 0 :(得分:0)
我首先使用代码将每位艺术家分别添加到我的数据库中来解决问题:
@artists = params["Composer Names"] | params["Arranger Names"] | params["Performer Names"]
@artists.each do |artist|
if artist.empty? == false
@exists = Artist.find_by_name(artist)
if @exists.nil?
@artist = Artist.new(:name => artist)
@artist.save
end
end
end
我可以使用push方法并使用以下代码将每个艺术家添加到正确的连接表中:
params["Composer Names"].each do |each|
if each.empty? == false
@album.composers << Artist.find_by_name(each)
end
end
就是这样!