[英]Remove element from ActiveRecord_Relation in rails
如何從 Rails 中的 ActiveRecord_Relation 中刪除最后一個元素?
例如,如果我設置:
@drivers = Driver.all
我可以通過以下方式將另一個名為 @new_driver 的驅動程序 object 添加到 @drivers:
@drivers << @new_driver
但是如何從@drivers 中刪除 object?
刪除方法似乎不起作用,即
@drivers.delete(0)
您可以使用reject!
方法,這將從集合中刪除對象而不影響數據庫
例如:
driver_to_delete = @driver.first # you need the object that you want removed
@drivers.reject!{|driver| driver == driver_to_delete}
也很晚了,但我來到這里尋找快速答案並通過自己思考完成;)
只是為了澄清不同的答案和 Rails 6.1 對已接受答案的評論:
OP 想從查詢中刪除一個條目,而不是將其從數據庫中刪除,因此任何使用delete
或destroy
的答案都是錯誤的(這將從您的數據庫中刪除數據。!)。
在 Ruby(以及 Rails)約定中,shebang 方法(以!
結尾)傾向於改變給定的參數。 所以reject!
將意味着修改源列表...但是ActiveRecord_Relation
基本上只是一個查詢,而不是一個條目數組!
所以你有兩個選擇:
@drivers.where.not(id: @driver_to_remove) # This still is an ActiveRecord_Relation
reject
(NO shebang) 將其轉換為數組並“手動”刪除不需要的條目:@drivers.reject{ |driver| driver == @driver_to_remove}
# The `reject` forces the execution of the query in DB and returns an Array)
從性能的角度來看,我個人會推薦第一個解決方案,因為它對 DB 來說稍微復雜一點,后者意味着在整個(最終是大的)數組上循環。
問題遲到了,但剛剛遇到了同樣的問題,希望這對其他人有所幫助。
reject!
不適用於 Rails 4.2 中的 ActiveRecord_Relation
drop(1)
是解決方案
在這種情況下, @drivers.drop(0)
將刪除關系的第一個元素
由於它是一個對象數組,您是否嘗試過編寫類似 @drivers.delete(@new_driver) 或 @drivers.delete(id: @new_driver.id) 的內容?
@group.avatars << Avatar.new
@group.avatars.delete(@group.avatars.last)
——
.destroy
您遇到的問題是您試圖在非集合對象上使用collection
方法。 您需要使用.destroy
ActiveRecord 方法從數據庫(以及集合)中刪除記錄:
@drivers = Driver.all
@drivers.last.destroy
——
范圍
.delete
將從數據庫中刪除記錄
如果要從數據庫中提取特定元素以填充@drivers
對象,則需要使用scope
:
#app/models/driver.rb
Class Driver < ActiveRecord::Base
scope :your_scope, -> { where column: "value" }
end
這將允許您調用:
#app/controllers/drivers_controller.rb
def index
@drivers = Driver.your_scope
end
我認為您對MVC 編程模式感到困惑-數據操作旨在發生在model
,而不是在controller
由於接受的答案在rails 5.2.3中不起作用,並且sevenseacat的正確答案隱藏在評論中。 這是答案。
@drivers.delete(@new_driver)
如上所述, reject!
在 Rails 4.2 中不起作用,但 delete 可以,所以@drivers.delete(@new_driver)
起作用,更一般地說:
@drivers.delete(Driver.where(your condition))
由於接受的答案不起作用,這里是 Rails 5.2 的解決方案
# to remove first element
@drivers = @drivers.second_to_last
#to remove last element
@drivers = @drivers.take(@drivers.size-1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.