Rails 6:如何从未持久化的ActiveRecord关联集合中删除元素?
解决未持久化ActiveRecord关联集合的内存删除问题
嘿,这问题我太熟悉了!你踩的坑在于:@library.books是ActiveRecord::Associations::CollectionProxy对象,不是普通的Ruby数组,所以直接调用delete_if会不符合预期——毕竟这个方法对于未持久化的集合并没有被正确实现。
不过别担心,咱们有两种简单的方法,完全在内存里完成过滤,不会碰数据库,等你调用@library.save的时候再一起把处理后的图书馆和书籍持久化:
方法1:使用keep_if直接修改集合
CollectionProxy本身支持keep_if方法,它会保留满足条件的元素,移除不满足的,直接在内存里修改关联集合:
@library.books.keep_if { |book| book.page_count >= 100 } @library.save
这个方法最直接,不需要额外转换,完全贴合Rails关联集合的操作逻辑。
方法2:转数组过滤后重新赋值
如果你更习惯数组的操作方式,可以先把关联集合转换成普通Ruby数组,过滤出符合要求的书籍后再重新赋值给@library.books:
@library.books = @library.books.select { |book| book.page_count >= 100 } @library.save
这种方式也完全是内存操作,赋值后原来不符合条件的书籍就会从关联集合中被移除,后续save时只会把留下的书籍和图书馆一起存入数据库。
为什么原来的delete_if不行?
简单来说,delete_if对于ActiveRecord的CollectionProxy来说,更多是为已持久化到数据库的集合设计的(会触发数据库删除操作),而你现在的场景是所有对象都还在内存里没存到数据库,所以这个方法在这里不适用。
内容的提问来源于stack exchange,提问作者TomDogg
相关产品推荐
相关产品推荐

