我有两个模型通过关联与has_many连接。
Book
可以有很多作者和Author
多本书。
在AuthorsController
来自API的update
行动中,我获得了作者的ID和一系列图书ID Parameters: {"books"=>"3,4,5", "id"=>"1"}
,我需要更新作者的书籍。
实现这一目标的最佳方法是什么?
我试过了author.books << Book.where(id: params[:books])
,但问题在于,如果一本书已经出现在作者的书中,那么它就会被复制。
答案 0 :(得分:8)
最有效的方法是使用:has_many关联参考。 视频:Rails 4 Guides
4.3.1 Methods Added by has_many
当您声明has_many关联时,声明类会自动获得与该关联相关的16个方法:
collection(force_reload = false)
collection<<(object, ...)
collection.delete(object, ...)
collection.destroy(object, ...)
collection=(objects)
collection_singular_ids
**collection_singular_ids=(ids)**
collection.clear
collection.empty?
collection.size
collection.find(...)
collection.where(...)
collection.exists?(...)
collection.build(attributes = {}, ...)
collection.create(attributes = {})
collection.create!(attributes = {})
示例:
答案 1 :(得分:2)
author.books << Book.where(id: params[:books])
执行不必要的数据库查询。
您可能需要删除数据库中已有的图书
books_array = params[:books].split(',') - author.books.pluck(:id)
books_array.each do |a|
author.author_books.build(book_id: a)
end
# I assumed author_books is the join table
答案 2 :(得分:0)
如果param [:books]是一串数字,您可以使用
将其转换为数组"3,4,5".split(',').map {|x| x.to_i}
-> [3, 4, 5]
然后使用Rails Collection methods,author.book_ids
应该返回一个可以减去的数组。因此,所有功能都类似于:
author.books << Book.where(id: params[:books].split(',').map {|x| x.to_i} - author.book_ids)
答案 3 :(得分:0)
我知道这可能为时已晚,但您也可以尝试
author.book_ids.push(params[:books]).flatten.uniq!
它有点短,只有一个请求。