有没有办法推迟持久化has_many:通过关联直到主要对象被保存?

时间:2014-09-22 14:07:55

标签: ruby-on-rails rails-activerecord has-many-through ruby-on-rails-4.1

我有一个模型需要在我想保存模型之前根据has_many :through关联验证可访问性。像这样:

class Document < ActiveRecord::Base
  belongs_to :organization
  has_many :category_documents
  has_many :categories, through: :category_documents

  validate :categories_are_accessible_to_organization

  private
    def categories_are_accessible_to_organization
      if (organization.category_ids & category_ids) != category_ids
        errors.add(:categories, "not accessible to the parent organization")
      end
    end
end

在新记录上似乎没有问题。但是,对于持久性记录,如果验证失败,则更新期间添加的类别将保持不变。有没有办法推迟这些连接模型的持久性,直到Document对象通过验证并通过任何内置机制保存?

2 个答案:

答案 0 :(得分:0)

要检查关联验证,您可以使用validates_associated :categories,从link-1link-2了解相关信息。

要检查Document的验证,请在更新操作中documents_controller.rb执行此操作,如下所示:

def update
  @document.attributes = document_params

  respond_to do |format|
    if @document.valid? && @document.update(document_params)
      format.html { redirect_to documents_path, notice: 'Document was successfully updated.' }
    else
      format.html { render action: 'edit' }
    end
  end
end

我认为您使用attributes作为活动记录来检查验证,然后保存任何关联的对象。

答案 1 :(得分:0)

您可以通过将验证移动到连接模型(即CategoryDocument)来实现相同的目标,就像这样

class CategoryDocument < ActiveRecord::Base
   belongs_to :category
   belongs_to :document

   before_save do
     false unless document.organization.category_ids.include?(category.id)
   end
end

这将使此类操作失败

Document.first.categories << category_that_does_not_satisfy_validation # raises ActiveRecord::RecordNotSaved