Максимальное количество связанных записей - PullRequest
3 голосов
/ 07 апреля 2011

Я хотел бы иметь максимальное количество связанных записей в модели.Например, у проекта есть много задач, но не более двадцати.

Как мне применить это правило?

Единственное решение, которое мне удалось найти, - это 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, чтобы она использовала приведенный выше запрос для вставки новогоrecord?

В настоящее время я использую пользовательский метод с ActiveRecord::Base.connection и вызываю его вместо .create или .save при new_record? == true.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Я не смог попробовать это, но я не понимаю, почему это не должно работать.

Шаг первый: определить валидатор для родительского объекта (это простая реализация - может/ следует сделать более общим):

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
0 голосов
/ 07 апреля 2011

Может быть, вы можете добавить некоторую проверку перед сохранением в вашу модель, которая проверяет, сколько ассоциированных моделей у нее уже есть, и выдавать ошибку проверки, если она превышает максимальное количество ассоциаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...