从rails中的ActiveRecord_Relation中删除元素

use*_*600 4 activerecord ruby-on-rails

如何从rails中的ActiveRecord_Relation中删除最后一个元素?

例如,如果我设置:

@drivers = Driver.all
Run Code Online (Sandbox Code Playgroud)

我可以通过执行以下操作将另一个名为@new_driver的Driver对象添加到@drivers:

@drivers << @new_driver
Run Code Online (Sandbox Code Playgroud)

但是如何从@drivers中删除对象?

删除方法似乎不起作用,即

@drivers.delete(0)
Run Code Online (Sandbox Code Playgroud)

小智 6

您可以使用该reject!方法,这将从集合中删除对象而不会影响db

例如:

driver_to_delete = @driver.first # you need the object that you want removed
@drivers.reject!{|driver| driver == driver_to_delete}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这在 Rails 6.1 中似乎不再起作用——我不确定什么时候改变了,但这里有错误消息:“NoMethodError:未定义的方法‘拒绝!’” 对于 #&lt;ActiveRecord::Relation [...]` (2认同)

gfd*_*gfd 6

也很晚了,但我到达这里寻找快速答案并通过自己思考完成;)

只是为了澄清不同的答案以及 Rails 6.1 对已接受答案的评论:

OP 希望从查询中删除delete一个条目,但不从数据库中删除它,因此任何带有或 的答案destroy都是错误的(这将从数据库中删除数据!!)。

在 Ruby(以及 Rails)约定中,shebang 方法(以 结尾!)倾向于更改给定的参数。因此reject!意味着修改源列表...但 anActiveRecord_Relation基本上只是一个查询,而不是一个条目数组!


所以你有两个选择:

  • 以不同的方式编写您的查询以明确表示您不需要某些 id:
@drivers.where.not(id: @driver_to_remove)  # This still is an ActiveRecord_Relation
Run Code Online (Sandbox Code Playgroud)
  • 在查询中使用reject(NO shebang) 将其转换为数组并“手动”删除您不需要的条目:
@drivers.reject{ |driver| driver ==  @driver_to_remove}
# The `reject` forces the execution of the query in DB and returns an Array)
Run Code Online (Sandbox Code Playgroud)

性能的角度来看,我个人推荐第一个解决方案,因为它对数据库来说稍微复杂一点,后者意味着在整个(最终很大)数组上循环。