如何验证更新的 has-many-through 集合

问题描述 投票:0回答:2

我试图弄清楚如何在使用 << collection operator. 更新集合时正确验证模型集合 在我们的遗留应用程序(Rails 3.2.1)中,我发现 platform_collection_obj.platforms 使用 << operator

更新

例子

collection.platforms << new_platform

在研究如何验证平台集合中的每个 平台 是否具有适当的数据时,我发现我应该使用自定义验证功能。所以我尝试将 each_platform_branch_id 验证函数添加到 PlatformCollections 模型。然而,我在测试中(通过 rails 控制台)发现验证没有被触发。

在阅读Has-Many-Association-Collection Info时,我遇到了这个

通过将对象的外键设置为集合的主键,将一个或多个对象添加到集合中。请注意,此操作会立即触发更新 SQL,而无需等待对父对象的保存或更新调用,除非父对象是新记录。这也将运行关联对象的验证和回调。

此摘录表明使用 << 在 collection.platforms 上执行更新不会触发父验证,在本例中为 PlatformCollection:each_platform_branch_id 验证函数。我知道手动执行 collection.save 会触发验证,但为时已晚 b/c << 已经更新了数据库。

所以重申这个问题是: 每当使用 << collection operator?

更新集合时,如何正确验证具有多个模型的集合

平台收藏模型

class PlatformCollection < ActiveRecord::Base
  belongs_to :tezt
  has_many :platform_collection_platforms, :order => "platform_collection_platforms.default DESC"
  has_many :platforms, :through => :platform_collection_platforms, :order => "platform_collection_platforms.default DESC"

  def each_platform_branch_id
    platforms.each do |p|
      if p.branch_id != @branch.id
        err_msg = "Invalid Platform: #{p.to_json} for PlatformCollection: #{self.to_json}. " \
                  "Expected Branch: #{@branch.id}, Actual Branch: #{p.branch_id}"
        errors.add(:platform, err_msg)
      end
    end
  end

平台模型

class Platform < ActiveRecord::Base
  attr_accessible :name
  belongs_to :branch
  has_many :platform_collection_platforms
  has_many :platform_collections, :through => :platform_collection_platforms
ruby ruby-on-rails-3
2个回答
0
投票

在这里完全不使用

<<
运算符 (
collection.platforms << new_platform
),也许最好显式创建 JOIN 记录?

即类似的东西:

collection.platform_collection_platforms.build(
  platform_collection: collection,
  platform: new_platform
)

(我的天哪,这是一组令人困惑的名字!!)

现在您可以完全控制

validate
.


0
投票

您可以使用 关联回调 在对象添加到关联(或从关联中删除)之前或之后执行检查或调用方法。比如像这样:

has_many :platforms, through:    :platform_collection_platforms,
                     before_add: :check_branch_id

private

def check_branch_id(platform)
  throw(:abort) if platform.branch_id != branch_id
end

顺便说一句。 Ruby on Rails 3.2.1 发布于 11 多年前,大约 7 年前达到生命周期结束,并且有一个长的众所周知的安全漏洞列表。我强烈建议将该应用程序更新到更新和更安全的版本。

© www.soinside.com 2019 - 2024. All rights reserved.