当前位置:  开发笔记 > 编程语言 > 正文

记录存在时,它不存在

如何解决《记录存在时,它不存在》经验,为你挑选了1个好方法。

鉴于这个简单的模型:

class Article < ActiveRecord::Base

  validates :title, presence: true
  validates :url, presence: true, uniqueness: true
  validates :topic, presence: true

  before_create :some_filter

private

  def some_filter
    self.noframe = false
  end
end

而事实是:

没有观察员

"noframe"列上没有索引

这怎么可能?

attrs = { title: "a", url: "http://www.example.com", topic: "test" }

Article.where(attrs).count
=> 0

Article.where(url:"http://www.example.com").count
=> 0

article = Article.new(attrs)
article.save

(0.2ms)  BEGIN
Article Exists (0.6ms)  SELECT  1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1
(0.3ms)  ROLLBACK

article.errors.full_messages
[]

调试器

将调试器放在"some_filter"方法中时,就会发生这种情况.

[12] pry(#
)> self.noframe = nil => nil [13] pry(#
)> self.valid? Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1 => true [14] pry(#
)> self.noframe = false => false [15] pry(#
)> self.valid? Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1 => true [16] pry(#
)> self.save Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1 => false

更多信息

为了使它更有趣,当我更改"some_filter"以将noframe设置为nil或true时,我可以创建任意数量的记录,而不会出现"文章存在"错误.

当我直接设置noframe属性而不是在before_create过滤器内部时,它也有效.

为什么这个解决方法有效?

我可以通过用"after_create"替换"before_create"并使用update_attributes(noframe:false)更新noframe属性来"修复"它.但为什么这是一个解决方案呢?update_attributes还调用所有回调和验证,为什么这在before_create中不起作用?



1> BroiSatse..:

before_create有一个不明显的属性 - 如果它返回false值它终止整个保存链.同样适用于所有before-*回调.您可以在回调文档中找到它.您的方法返回false,因此整个事务回滚.将其更改为:

def some_filter
  self.noframe = false
  true
end

一切都会奏效.

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有