如何在before_save关联回调中添加validation错误

我有两个模型:折扣已经属于许多商业。

我想validation折扣总是至少有一个业务,以及另一个条件(例如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 

然而,这不起作用(没有引发validation错误),我意识到这可能是因为它只是一个回调,而不是validation。 我怎么能编码它所以我可以像我做自定义validation一样使用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 

可能是您在before_remove回调中的语法或validation方法本身发生的事情。 您还可能希望在回调方法中添加一些调试代码,以查看它是否在那里进行。

*请注意,只有在回调方法中引发exception时才会停止事务。 既然如此,您可能希望在控制器中处理exception逻辑以重新呈现操作:

 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 

请注意关联回调文档。

您可以使用validates方法:presence => true

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

在关联validation器上使用:presence => true将确保至少存在一个关联成员。