【问题标题】:Ruby Delete multiple objects by associationRuby 通过关联删除多个对象
【发布时间】:2018-08-09 03:41:06
【问题描述】:

我的应用需要销毁所有成员少于两个的团队。

这种方法似乎有效,但我希望尽可能将其“rubify”到一行。

  @consultancy.teams.reverse.each do |team|
    team.destroy if team.users.count < 2 
  end

我正在尝试做类似以下的事情,但我收到了拒绝错误!方法。

@consultancy.teams.reject!{|x| x.users.count < 2}

NoMethodError: undefined method `reject!' for #<Team::ActiveRecord_Associations_CollectionProxy:0x00000003f72850>

.delete_all 也会抛出错误。

@consultancy.teams.select{|x| x.users.count < 2}.delete_all

NoMethodError: undefined method `delete_all' for #<Array:0x0000000b72dcf0>

提前感谢您的任何见解。

【问题讨论】:

  • rejectdelete_all 出现什么错误?
  • 好点。我编辑了问题以包含错误消息。
  • 这个问题应该有助于解决这个问题:stackoverflow.com/questions/31409792/… 基本上,@consultancy.teams 不是一个数组

标签: ruby


【解决方案1】:

select 作用于数组,但delete_all 是活动记录关系方法。

你可以的

@consultancy.teams.select{|x| x.users.count < 2}.map(&:delete)

但更好的方法可能是将计数选择作为查询的一部分。

@consultancy.teams.joins(:users).group('teams.id').having('count(users.id) < 2').destroy_all

【讨论】:

  • 答案的最后一部分是我要写的。不错!
  • 我很好奇为什么你们都喜欢第二种方法。有什么优势?
  • 大部分“繁重的工作”是由数据库完成的,而不是由应用程序完成的,并且数据库操作总是能提供更好的性能。例如@consultancy.order(:name) 按名称顺序带回所有记录,@consultancy.sort_by(&amp;:name) 带回所有记录,转换为数组,然后按name 属性对数组进行排序。如果你发现你正在执行数组操作,那么看看是否有一个 SQL 等效命令总是值得的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多