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:

  1. instead of using first_or_create use find_or_create_by

    blog.find_or_create_by( name: 'first blog' ) 
  2. use unscoped in callbacks includes query like:

    def print_other_name   # example, running query here.   blog = blog.unscoped.first end 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -