最大关联记录数

时间:2011-04-07 07:39:53

标签: sql ruby-on-rails ruby-on-rails-3 activerecord

我想在模型上拥有最大数量的关联记录。 例如。一个项目有很多任务,但不超过二十个。

如何执行此规则?

到目前为止,我能够提出的唯一解决方案是 INSERT INTO...SELECT这样的查询:

INSERT INTO
  tasks (`id`,`project_id`,`title`,`body`)
SELECT
  NULL, ?, ?, ?
FROM
  tasks
HAVING
  count(id) < MAX_NUMBER_OF_TASKS
LIMIT 1;
  1. 据我所知,这将保证插入的任务数量最多。我这是对的吗?
  2. 有没有'Rails方式'来做这件事?
  3. 是否可以覆盖ActiveRecord / Task模型,以便它使用上面的查询 插入新记录?
  4. 我目前正在使用ActiveRecord::Base.connection的自定义方法 并在.create时调用{而不是.savenew_record? == true

2 个答案:

答案 0 :(得分:2)

我无法尝试这个,但我不明白为什么它不起作用。

第一步:在父对象上定义验证器(这是一个简单的实现 - 可以/应该更通用):

class Project < ActiveRecord::Base
  validate :max_tasks

  def max_tasks
    if tasks.count > 20
      errors.add_to_base("Should not have more than 20 tasks")
    end
  end
end

第二步:从任务开启项目验证:

class Task < ActiveRecord::Base
  validates_associated :project
end

我认为你应该做生意。当您尝试保存新任务时,它将验证关联的项目,如果(现在)关联的任务超过20个,则验证将失败。

如果你想让它更通用,你可以做类似的事情:

class NumberOfAssociatedValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if options[:maximum] && record.send(attribute).count > options[:maximum]
      record.errors[attribute] << "must not have more than #{options[:maximum]}"
    end
    if options[:minimum] && record.send(attribute).count < options[:minimum]
      record.errors[attribute] << "must not have less than #{options[:minimum]}"
    end
  end
end

class MyModel < ActiveRecord::Base
  validates :my_association, :number_of_associated => {:maxiumum => 20}
end

答案 1 :(得分:0)

可能您可以为模型添加一些预保存验证,检查已有的相关模型数量,如果超过最大关联数,则抛出验证错误。