Ruby on rails ActiveRecord在事务中保存无效模型,并且不回滚

Ruby on rails ActiveRecord在事务中保存无效模型,并且不回滚,ruby-on-rails,activerecord,transactions,Ruby On Rails,Activerecord,Transactions,我有模型 class Agency < ActiveRecord::Base SPECIALIZATIONS_LIMIT = 5 has_many :specializations has_many :cruise_lines, through: :specializations protected def validate_specializations_limit errors.add(:base, "Agency specializatio

我有模型

class Agency < ActiveRecord::Base
  SPECIALIZATIONS_LIMIT = 5

  has_many :specializations
  has_many :cruise_lines, through: :specializations

  protected 

    def validate_specializations_limit
      errors.add(:base, "Agency specializations max limit is #{SPECIALIZATIONS_LIMIT}. Deselect some before saving.") if specializations.count > SPECIALIZATIONS_LIMIT
    end
end

class CruiseLine < ActiveRecord::Base
  has_many :specializations
  has_many :agencies, through: :specializations
end

class Specialization < ActiveRecord::Base
  belongs_to :agency, inverse_of: :specializations
  belongs_to :cruise_line, inverse_of: :specializations
end
当我试图像这样保存数据时(如果超出限制,则返回
false
),它会显示错误闪烁消息,但无论如何都会保存关系,所以代理再次无效

module SpecializationService
  def self.update_agency_specializations(agency, params)
    attributes = params.require(:agency).permit( { cruise_line_ids: [] } )

    agency.cruise_line_ids = attributes[:cruise_line_ids].select{ |x| x.to_i > 0 }
    agency.save
    !agency.errors.present?
  end
end
保存超过限制的专门化后,代理模型不能在其他页面上更新,因为它总是无效的

更新

我已经检查了代理机构。专业化。计数

1) 在事务正确之前,代理是有效的(若它确实正确,但表单包含太多的专门化而无法保存)

2)在销毁专业化并创建新的专业化后,它们的计数是
0
(为什么??),因此验证通过了


3) 超过保存计数后(如果我选择了太多),代理-无效。

不使用.count,使用.length。count使用对数据库的调用,而length将检查内存中的对象

有关计数/大小/长度的更多信息,请参阅本文:

专门化。如果模型未保存且相关对象被更改,则计数似乎不可靠。在验证过程中尝试检查这是什么值:它可能实际显示一些有效的内容,保存它,然后以这种方式使其无效。我已经更新了
count
上的注释。结果是,在构建计数为
0
之后:(也许,
倒数在某个地方是不正确的?
module SpecializationService
  def self.update_agency_specializations(agency, params)
    attributes = params.require(:agency).permit( { cruise_line_ids: [] } )

    agency.cruise_line_ids = attributes[:cruise_line_ids].select{ |x| x.to_i > 0 }
    agency.save
    !agency.errors.present?
  end
end