【问题标题】:Rails handling ActiveRecord::AssociationTypeMismatch as exceptionRails 将 ActiveRecord::AssociationTypeMismatch 处理为异常
【发布时间】:2014-05-09 05:26:33
【问题描述】:

我有以下代码:

def set_tags_from_string
    list = self.tags_string.split(/ /)

    list.each do |tag|
        begin
            self.partner_tags << PartnerTag.find_by(name: tag)
        rescue
            self.partner_tags << PartnerTag.create(name: tag)
        end
    end
end

当我尝试将PartnerTag 推入self.partner_tags 并且该标签尚不存在时,问题就出现了。控制台显示如下:

ActiveRecord::AssociationTypeMismatch: PartnerTag(#28272720) expected, got NilClass(#8501040)

我希望能够将此作为异常处理,但它仍然给出错误。我以前从未在 Ruby 中进行过异常处理,所以我想我可能会遗漏一些东西,但我遵循了 this 教程,但我没有看到我遗漏了什么。 Rails API 说它实际上是一个异常,最终继承自StandardErrorThe Ruby documentation 说救援子句应该处理所有StandardErrors,所以我不知道我做错了什么。

【问题讨论】:

    标签: ruby-on-rails ruby exception activerecord exception-handling


    【解决方案1】:

    试试这个:

    self.partner_tags << PartnerTag.find_by(name: tag) || PartnerTag.create(name)
    

    此外,如果您使用的是 Rails 4,您可以这样做:

    self.partners_tags << PartnerTag.find_or_create_by(tag: name)
    

    但是请注意,除非您在数据库中具有唯一约束,否则它不会阻止您以两个相同的标签结束。

    【讨论】:

    • PartnerTag 在类定义中具有唯一性验证。在防止两个相同的标签方面,这应该相当于一个 db 约束,对吧?
    • @Hugo - 我昨天对此进行了讨论,不幸的是它没有。可能有两个进程并行工作,同时检查标签是否存在,然后每个进程都会创建一个新进程。这不应该发生在像 webrick 这样的单线程服务器上,但是如果您决定使用 Unicorn 或者如果您的应用程序在多个服务器上运行,这将成为一个严重的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    相关资源
    最近更新 更多