How can I get this create_table statement on one line?

32 views
Skip to first unread message

Robert Phillips

unread,
Mar 9, 2018, 3:42:06 AM3/9/18
to Ruby on Rails: Talk
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

Hassan Schroeder

unread,
Mar 9, 2018, 11:33:51 AM3/9/18
to rubyonrails-talk
On Fri, Mar 9, 2018 at 12:42 AM, Robert Phillips
<robert.p...@gmail.com> wrote:

> 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 }

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!
--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
twitter: @hassan
Consulting Availability : Silicon Valley or remote

Robert Phillips

unread,
Mar 10, 2018, 9:34:49 PM3/10/18
to Ruby on Rails: Talk
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? 

Walter Lee Davis

unread,
Mar 11, 2018, 10:36:30 AM3/11/18
to rubyonra...@googlegroups.com

> On Mar 10, 2018, at 9:34 PM, Robert Phillips <robert.p...@gmail.com> wrote:
>
> 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
> --
> 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-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/79c19806-23ec-4af6-b2e2-e1d590ecea18%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Robert Phillips

unread,
Mar 19, 2018, 12:19:00 AM3/19/18
to Ruby on Rails: Talk


On Sunday, 11 March 2018 14:36:30 UTC, Walter Lee Davis wrote:

.........................................
 
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.



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

Walter Lee Davis

unread,
Mar 19, 2018, 8:36:28 PM3/19/18
to rubyonra...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages