Учитывая эту простую модель:запись существует, когда он не
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(#<Article>)> self.noframe = nil
=> nil
[13] pry(#<Article>)> self.valid?
Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1
=> true
[14] pry(#<Article>)> self.noframe = false
=> false
[15] pry(#<Article>)> self.valid?
Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."url" = 'http://www.example.com' LIMIT 1
=> true
[16] pry(#<Article>)> 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 либо ноль, либо правда, я могу создать столько записей, сколько я хочу без «Статья Exists " ошибка.
Он также работает, когда я устанавливаю атрибут noframe напрямую, а не внутри фильтра before_create.
Почему это обходное решение работает?
Я могу «исправить» его, заменив «before_create» на «after_create» и обновив атрибут noframe дополнительно с помощью update_attributes (noframe: false). Но почему это решение? update_attributes также вызывает все обратные вызовы и проверку, поэтому почему это не работает в before_create?
Имеет смысл. Тем не менее, менее сложное сообщение об ошибке будет приятным. Я подал сообщение об ошибке: https://github.com/rails/rails/issues/22713 – Sergey