Rails过滤掉关联中删除的记录

时间:2013-09-01 04:26:19

标签: ruby-on-rails activerecord

我的rails应用程序需要对某些记录进行“软”删除,以便在不实际从数据库中删除的情况下将其取消激活。目前我使用“is_deleted”标志实现了它。

我的问题是,是否有处理涉及此模型的关联的最佳实践。例如:

class Foo
  attr_accessible :is_deleted
  scope :active, -> { where(is_deleted:false) }  
  belongs_to :bar   
end

class Bar
   has_many :foos
end

我正在试图弄清楚如何设置Bar模型,因为它知道它通常只处理'活跃'的foos。

我想出了一些想法,并想知道是否有任何优点/缺点使用其中一个。

  • 在has_many声明中使用“condition”限定符来过滤掉已删除的项目。
  • 在Bar上创建“active_foos”方法,仅返回未删除的项目。
  • 只需使用“acts_as_paranoid”宝石。对于我需要的东西感觉有点重量级,但也许这是最简单的。

2 个答案:

答案 0 :(得分:2)

使用acts_as_paranoid的第三个选项是最好的,因为它占用了大部分重量级提升,它还为您提供了其他选项来加载所有记录,无论是删除还是在某个时间戳后删除。最好使用已编写和测试过的代码,然后自己重​​新发明轮子。

随着时间的推移,随着应用程序的增长,您需要更多&软删除记录的更多选项和自定义查询。所以,请使用acts_as_paranoid。

答案 1 :(得分:2)

techwineet的建议很不错。但对于当前代码,最简单的解决方案是将“活动”设置为默认范围,如果您需要经常处理它。

class Foo
  attr_accessible :is_deleted
  default_scope   -> { where(is_deleted:false) }  
  scope :active,  -> { where(is_deleted:false) }
  scope :deleted, -> { where(is_deleted:true) }
  belongs_to :bar   
end

class Bar
   has_many :foos
   # optional delegation
   delegate :active, :delete, to: :foos, prefix: true
end

Foo.all           #=> Return active foos. Or better to use Foo.scoped
Foo.deleted       #=> Return all deleted foos
Foo.unscoped      #=> Return all foos, both active and deleted

bar = Bar.first
bar.foos          #=> Return associated active foos
bar.foos.active   #=> Return associated active foos
bar.foos.deleted  #=> Return associated deleted foos
bar.foos.unscoped #=> Return all associated foos

# Optional delegation
bar.foos_active   #=> Return associated active foos
bar.foos_deleted  #=> Return associated deleted foos