簡體   English   中英

從 rails 中的 ActiveRecord_Relation 中刪除元素

[英]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 想從查詢中刪除一個條目,而不是將其從數據庫中刪除,因此任何使用deletedestroy的答案都是錯誤的(這將從您的數據庫中刪除數據。!)。

在 Ruby(以及 Rails)約定中,shebang 方法(以!結尾)傾向於改變給定的參數。 所以reject! 將意味着修改源列表...但是ActiveRecord_Relation基本上只是一個查詢,而不是一個條目數組!


所以你有兩個選擇:

  • 以不同的方式編寫您的查詢,具體說明您不需要某些 ID:
@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM