ruby on rails - When using first_or_create, in the after_create callback, the Model queries get extra conditions added automatically -
for explanation purposes, i'm going create brand new rails (3.2.13) project using sqlite.
rails new testapp cd testapp/ rake db:create rails g model blog name:string description:string rake db:migrate this content of blog model.
class blog < activerecord::base attr_accessible :description, :name after_create :print_other_name private def print_other_name # example, running query here. blog = blog.first end end then open rails console.
1.9.3-p125 :001 > blog = blog.where( name: 'first blog' ).first_or_create!( description: 'this first blog' ) blog load (0.2ms) select "blogs".* "blogs" "blogs"."name" = 'first blog' limit 1 (0.1ms) begin transaction sql (63.9ms) insert "blogs" ("created_at", "description", "name", "updated_at") values (?, ?, ?, ?) [["created_at", thu, 09 may 2013 11:30:31 utc +00:00], ["description", "this first blog"], ["name", "first blog"], ["updated_at", thu, 09 may 2013 11:30:31 utc +00:00]] ======>>>>>>> blog load (0.6ms) select "blogs".* "blogs" "blogs"."name" = 'first blog' limit 1 (1.5ms) commit transaction => #<blog id: 1, name: "first blog", description: "this first blog", created_at: "2013-05-09 11:30:31", updated_at: "2013-05-09 11:30:31"> in above code block, please @ query has been run after insert query:
blog load (0.6ms) select "blogs".* "blogs" "blogs"."name" = 'first blog' limit 1 this query has been generated blog.first line in model's after_create.
what should have been simple limit 1 query without conditions, has name condition added on query. , after lot of testing, realised condition being added on condition mentioned in blog.where( name: 'first blog' ).first_or_create!.... line.
in other words, whatever conditions use in where before first_or_create seems added automatically queries run in after_create callback.
i can't imagine why expected behaviour, if is, can't find documented anywhere.
does have insight behaviour? breaking queries in after_create callbacks.
the first_or_create wraps whole query in scope defined clause. can solve in 2 ways:
instead of using
first_or_createusefind_or_create_byblog.find_or_create_by( name: 'first blog' )use
unscopedin callbacks includes query like:def print_other_name # example, running query here. blog = blog.unscoped.first end
Comments
Post a Comment