Как добавить ошибку проверки в обратные вызовы ассоциации before_save - PullRequest
8 голосов
/ 30 января 2012

У меня есть две модели: Скидка есть и принадлежит многим Businsses.

Я хочу подтвердить, что у Дисконта всегда есть хотя бы один бизнес вместе с другим условием (например, active?). Я попробовал следующее:

class Discount < ActiveRecord::Base
  has_and_belongs_to_many :businesses,
    before_remove: :validate_publish_status

  def validate_publish_status(*arg)
    if active? && businesses.count == 0
      errors[:active] << 'discount with no business'
    end
  end
end

Однако это не работает (ошибок проверки не возникало), и я понял, что это, вероятно, потому, что это всего лишь обратный вызов, а не проверка. Как я могу кодировать его, чтобы я мог использовать errors, как я делаю пользовательскую проверку?

Действие контроллера у меня (для ajax):

  def remove
    @business = Business.find(params[:business_id])
    if @business.in? @discount.businesses
      @discount.businesses.delete(@business)
    end
    render json: @business.as_json(only: [:id, :type, :name, :address],
                                   methods: [:city_name, :country_name]).
      merge(paths: paths_for(@discount, @business))
  rescue ActiveRecord::RecordInvalid # even tried the generic Exception
    respond_to do |f|
      f.json { render json: {error: $!.message}, status: 403 }
    end
  end

Ответы [ 2 ]

9 голосов
/ 30 января 2012

Может быть ваш синтаксис обратного вызова before_remove или что происходит в самом методе проверки.Вы также можете добавить некоторый код отладки в метод обратного вызова, чтобы увидеть, что он там делает.

* Обратите внимание, что транзакция будет остановлена ​​только в случае возникновения исключения в методе обратного вызова.Поскольку дело обстоит именно так, вы, вероятно, захотите обработать логику исключений в вашем контроллере для повторного рендеринга действия:

class Discount < ActiveRecord::Base
  has_and_belongs_to_many :businesses, :before_remove => :validate_publish_status

  def validate_publish_status(*args)
   if yyy? && businesses.count == 0
    errors.add(:yyy,'discount with no business')
    raise "Unable to remove business."
   end
  end

end

Суть контроллера:

  def update
    @company.find(params[:id])
    if @company.update_attributes(params[:company])
      ...
    else
      render :action => 'edit'
    end
  rescue
    render :action=>'edit'
  end

Обратите внимание на Документация обратного вызова ассоциации.

2 голосов
/ 30 января 2012

Для этого вы можете использовать проверяет метод с :presence => true.

class Discount < ActiveRecord::Base
  has_and_belongs_to_many :businesses
  validates :businesses, :presence => true
end

Использование :presence => true в валидаторе ассоциации обеспечит существование хотя бы одного члена ассоциации.

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