2015-12-14 20 views
0

我有2個模型通過關聯與has_many連接。 Book可以有很多作者和Author許多書籍。更新來自ID數組的has_many關聯

AuthorsController in update來自API的操作我得到了作者的ID和一個書號ID Parameters: {"books"=>"3,4,5", "id"=>"1"}的數組,我需要用它們更新作者的書。 實現該目標的最佳方法是什麼?

我試過author.books << Book.where(id: params[:books])但這裏的問題是,如果一本書已經在作者的書中,它將被複制。

+1

最簡單的方法解決你的問題是將你的params從'books'改爲'book_ids',然後ActiveRecord會照顧休息。請參閱[ActiveRecord關聯](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many)和'collection_singular_ids = ids' –

回答

1
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 
0

書如果param [:書籍]是一串數字,你可以用轉換爲數組

"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) 
0

我知道這可能是太晚了,但你也可以嘗試

author.book_ids.push(params[:books]).flatten.uniq! 

它會更短一點,一個單一的請求。

5

最有效的方法是使用: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 = {}) 

例子:

enter image description here