How can I get this create_table statement on one line?

If I go to rails console

I can’t get a create_table statement onto one line

irb(main):019:0> ActiveRecord::Migration.create_table :wers { |t| t.string :name }

SyntaxError: (irb):19: syntax error, unexpected ‘{’, expecting end-of-input

Migration.create_table :wers { |t| t.string :name }

I can see this works

irb(main):032:0> 5.times do |r|

irb(main):033:1* puts “a”

irb(main):034:1> end

and this works

irb(main):031:0> 5.times { |r| puts “a”}

And I can see this works

irb(main):039:0> ActiveRecord::Migration.create_table :haae do |t|

irb(main):040:1* t.string :firstname

irb(main):041:1> end

– create_table(:haae)

(4.0ms) CREATE TABLE “haae” (“id” INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, “firstname” varchar)

-> 0.0057s

=> []

irb(main):042:0>

But I still can’t get that create_table line onto one line

irb(main):019:0> ActiveRecord::Migration.create_table :wers { |t| t.string :name }

SyntaxError: (irb):19: syntax error, unexpected ‘{’, expecting end-of-input

Migration.create_table :wers { |t| t.string :name }

I was able to replace the do and end on the 5.times line… with {…} and put it on one line, but I can’t get the same to work for create_table

I’m ok with putting it on multiple lines but I like the flexibility of being able to put it on one line should I so wish

Thanks

ActiveRecord::Migration.create_table(:wers){ |t| t.string :name }
-- create_table(:wers)
   (60.1ms) SET NAMES utf8, @@SESSION.sql_mode =
CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'),
',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0,
@@SESSION.wait_timeout = 2147483
   (192.1ms) CREATE TABLE `wers` (`id` bigint NOT NULL AUTO_INCREMENT
PRIMARY KEY, `name` varchar(255)) ENGINE=InnoDB
   -> 0.4446s
=> nil
2.5.0 (main):0 >

You need to separate the argument ":wers" from the block with parens.

HTH!

Thanks, that works

When I do create_table (:gars) { |t| t.string :name }

What exactly is that syntax… Like is the string of t.string, a method of the t object, that takes a symbol?

Thanks, that works

When I do create_table (:gars) { |t| t.string :name }

What exactly is that syntax.. Like is the string of t.string, a method of the t object, that takes a symbol?

Here's the nutshell:

Ruby's block syntax may be written two ways. Your example is the one-liner form. You may be used to seeing this:

@whatever.each do |something|
  something.do_something
end

That could also be written as

@whatever.each{ |something| something.do_something }

It's just a physically-compact form, it does the same thing in one line as three. To answer your other question, whatever is between the pipes is the object that gets passed into the block. In the case of create_table, it's a method that accepts a block, rather than an iterator (as in my first example) that yields instances to one. If there is an argument before the block, it is optionally inside parentheses (for the multi-line do-end form), and required to be inside parentheses if you're using the one-liner format.

Here's a multi-line block format migration method:

    create_table :friendly_id_slugs do |t|
      t.string :slug, :null => false
      t.integer :sluggable_id, :null => false
      t.string :sluggable_type, :limit => 50
      t.string :scope
      t.datetime :created_at
    end

So you have the method create_table(), which is sent one to two arguments: the table name to be created, and a hash of options, and then optionally passed a block with the details of the table. "t" is the name you gave the block, just the same as "something" in my example. The name itself is not significant, but off of that block hangs the rest of the details for create_table to use when making your table. If you don't pass the block, then the table is created without any columns.

https://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/create_table

Walter

Thanks.

Isn’t ‘t’ a formal parameter for/of the block, rather than a name of the block? I have read that blocks are anonymous/nameless.

The main thing that had me puzzled but I think I can see better now, were lines like t.integer :abc But I see now that integer is a method that makes a column of type integer and takes a symbol as parameter. And the reason why it’s named in such a way that it doesn’t look like a verb, / doesn’t look like a method, is because Active Record uses a DSL (Domain Specific Language), which is still Ruby but designed to not look like normal Ruby even though it is

Yes, you are absolutely correct. Block (if you squint) is kind of like a Proc, and the arguments in between the pipes are the parameters passed into the block.

Walter