Ruby on Rails Sunday, March 18, 2018

What, if any, partial reload, does creating a table from the rails console do?

I'll explain what I mean

C:\rubytest\proj>rails new abc1
..................

C:\rubytest\proj>cd abc1

C:\rubytest\proj\abc1>cd app\models

C:\rubytest\proj\abc1\app\models>notepad blah.rb

C:\rubytest\proj\abc1\app\models>type blah.rb
class Blah < ApplicationRecord
end
C:\rubytest\proj\abc1\app\models>rails console
Loading development environment (Rails 5.1.5)
irb(main):001:0> Blah.new
ActiveRecord::StatementInvalid: Could not find table 'blahs'
        from (irb):1

^^ No surprises there.

irb(main):002:0> am=ActiveRecord::Migration
=> ActiveRecord::Migration
irb(main):003:0> am.create_table(:blahs)
-- create_table(:blahs)
   (0.0ms)  SELECT sqlite_version(*)
   (6.0ms)  CREATE TABLE "blahs" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)
   -> 0.0098s
=> []
irb(main):004:0> Blah.new
=> #<Blah id: nil>

^^^ There we see that the rails console has re-read the database in some sense  since it is now aware that we have a :blahs table.


irb(main):005:0> am.drop_table :blahs
-- drop_table(:blahs)
   (7.0ms)  DROP TABLE "blahs"
   -> 0.0087s
=> []
irb(main):009:0> am.connection.tables
=> []
irb(main):010:0> Blah.new
=> #<Blah id: nil>

^^^ So we see that  drop_table  doesn't lead to any kind of a refresh of the rails console.  

  The rails console is in some ways oblivious to the fact that the table has been dropped.    am.connection.tables works fine..  it picks up that the table has been dropped.  But given that I can still do Blah.new  it shows the rails console hasn't done any kind of full refresh..  I know that if I was to exit the rails console and go back in, or do reload!, then it'd pick up that the table is dropped and Blah.new will then give an error as it shoudl.

irb(main):011:0> reload!
Reloading...
=> true
irb(main):012:0> Blah.new
ActiveRecord::StatementInvalid: Could not find table 'blahs'
        from (irb):12


irb(main):013:0> am.create_table(:blahs)
-- create_table(:blahs)
   (0.0ms)  SELECT sqlite_version(*)
   (3.0ms)  CREATE TABLE "blahs" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)
   -> 0.0048s
=> []
irb(main):014:0> Blah.new
=> #<Blah id: nil>
irb(main):015:0> am.drop_table :blahs
-- drop_table(:blahs)
   (5.0ms)  DROP TABLE "blahs"
   -> 0.0063s
=> []
irb(main):016:0> am.create_table(:blahs) {|t| t.string :gg}
-- create_table(:blahs)
   (4.0ms)  CREATE TABLE "blahs" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "gg" varchar)
   -> 0.0059s
=> []
irb(main):017:0> Blah.new
=> #<Blah id: nil>

Here after dropping the table.. knowing that rails console doesn't pick that up in a way that will affect Blah.new  

I then do  create_table  to see if it picks that up.. And the strange thing is it doesn't really.      The create table line I did made a new column.

Rails Console is still picking up the earlier create_table.


irb(main):018:0> reload!
Reloading...
=> true
irb(main):019:0> Blah.new
=> #<Blah id: nil, gg: nil>
irb(main):020:0>

of course when I do a reload! which seems to be like exiting and reentering the console, then it picks it up.

But it suggests to me that create_table might lead  some kind of semi-refresh.. of the rails console

When the rails console first starts, then when create_table is done first time, e.g.  at a time when the table doesn't exist and the rails console is fully aware that the table doesn't exist. So when Blah.new gives the error.  Then, when create_table is done that first time,  Blah.new works afterwards.  So rails  console has done some kind of refresh at least in part.

But if the table is dropped and a new create_table line is done, then rails console doesn't refresh.  It remains on the old create_table.

Does the rails console do a "reload!" when it's aware that a table has been dropped.. But not when it's not aware?   

So if you drop a table then run reload!, then create_table, then it seems to do a refresh or reload!, as it then picks up the new table.

And if you drop a table  then  ActiveRecord::Migration.connection.tables  picks up the latest situation..   though Blah.new acts like it's still there. (though granted Blah.new.valid? will be false and Blah.new.save will fail)

But if you drop a table and don't reload, and you  then create a table, then it doesn't register that the table has been dropped and recreated..  i.e. when you then do Blah.new it shows the original table.  Then if you do "reload!" it shows the recreated table.

I'm hypothesising no doubt wrongly, when I speak of partial reload.. But i'd like to know what is actually happening there.

Thanks

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/bc5d1423-eb29-4497-af31-e0a69ba90c95%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment