Rails:验证记录数的正确方法

时间:2015-03-09 15:46:21

标签: ruby-on-rails

就我而言,user有很多categories,我想阻止用户删除他的上一个category,这就是我在Categories#destroy中所做的:

  def destroy
    if current_user.categories.count > 1
      @category.destroy
      redirect_to categories_url
    else
      flash[:category_notice] = "Cannot destroy the last category"
      redirect_to categories_url
    end
  end

显然,这解决了这个问题。但我想知道是否有正确的方法呢?或者这很好吗?

2 个答案:

答案 0 :(得分:4)

我更喜欢在模型中执行此操作(当您在控制台上工作时,可以防止破坏最后一条记录)。 例如,您可以在类别模型中使用callback

before_destroy: check_if_last

def check_if_last
    raise "Can't destroy last category!" if self.user.categories.count  == 1
end

编辑:为了避免用户对象出现竞争条件,locking应该这样做。

答案 1 :(得分:0)

我会在用户上添加一个计数器。因此,用户具有categories_count字段,默认值为0.

add_column :users, :categories_count, :integer, default: 0

然后

class User
  has_many :categories
end

class Category
  belongs_to :user, counter_cache: true
end

您可能想要使用reset_counters

User.find_each do |u|
 User.reset_counters(u.id, :categories)
end

将计数器设置为适当的值。

然后你可以做

if current_user.categories_count > 1
  @category.destroy
  redirect_to categories_url
else
  flash[:category_notice] = "Cannot destroy the last category"
  redirect_to categories_url
end

这样可以缓存计数,并为您保存查询。它并没有多大区别,你的方式很好。