Предотвратить пустую таблицу соединений - PullRequest
0 голосов
/ 30 марта 2012

Отношения

class Promotion < ActiveRecord::Base
  has_many :promotion_sweepstakes,

  has_many :sweepstakes,
    :through => :promotion_sweepstakes
  end

class PromotionSweepstake < ActiveRecord::Base
  belongs_to :promotion
  belongs_to :sweepstake
end

class Sweepstake < ActiveRecord::Base
  # Not relevant in this question, but I included the class
end

Итак, промоушен has_many Тотализатор через объединяющий стол PromotionSweepstake.Это устаревшая схема БД, поэтому наименование может показаться немного странным, а некоторые свойства self.table_name == и foreign_key пропущены.

Природа этого приложения требует , что по крайней мереодна запись в таблице объединения присутствует для promoId, поскольку отсутствие тотализатора может привести к поломке приложения.

Первый вопрос

Как можно гарантировать, что в PromotionSweepstake всегда есть одна запись дляПродвижение?При создании должен быть включен как минимум один Sweepstake.id, и как только в нем создается запись в объединяемой таблице, должен составлять минимум один для каждого Promotion / promo_id .

Secondвопрос (другой вариант)

Если предыдущее предложение было бы невозможным, что я сомневаюсь в истинности, есть другой способ решения проблемы.Есть своего рода "Sweepstake по умолчанию" с определенным идентификатором.Если через форму будут удалены все sweepstake_ids (чтобы удалить все записи об Акции в таблице присоединения), могу ли я создать новую запись в PromotionSweepstake?

псевдо-код (вид)

удалить promo_sweepstake с идентификаторами [1, 4, 5], где Promotion_id = 1, если в промоушене с id = 1 нет поощрений_свободных стейков.*

1 Ответ

1 голос
/ 04 апреля 2012

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

class Promotion < ActiveRecord::Base
  has_many :promotion_sweepstakes
  has_many :sweepstakes,
    :through => :promotion_sweepstakes
  validates :sweepstakes, :presence => true
end

Чтобы обеспечить согласованность при попытке удалить или обновить Sweepstake или PromotionSweepstake, вам необходимо написать свои собственные проверки для этих двух классов. Им придется проверить, действительны ли ранее упомянутые Акции, т. Е. Все еще есть лотереи.

Простое решение будет использовать validates :sweepstakes, :presence => true в Promotion. После обновления указанных транзакций PromotionSweepstakes или Sweepstakes вам нужно будет позвонить по номеру Promotion#valid? в ранее указанных Акциях. Если они недействительны, вы откатываете транзакцию, поскольку модификация нарушает последовательность.

В качестве альтернативы вы можете использовать before_destroy в PromotionSweepstake и Sweepstake, чтобы предотвратить изменения, нарушающие ваши требования к согласованности.

class PromotionSweepstake < ActiveRecord::Base
  belongs_to :promotion
  belongs_to :sweepstake
  before_destroy :check_for_promotion_on_destroy

private

  def check_for_promotion_on_destroy
    raise 'deleting the last sweepstake' if promotion.sweepstakes.count == 1
  end
end

class Sweepstake < ActiveRecord::Base
  has_many :promotion_sweepstakes
  has_many :promotions, :through => :promotion_sweepstakes
  before_destroy :check_for_promotions_on_destroy

private

  def check_for_promotions_on_destroy
    promotions.each do |prom|
      raise 'deleting the last sweepstake' if prom.sweepstakes.count == 1
    end
  end

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