# How ActiveRecords create tables

**URL:** <https://www.ruby-forum.com/t/how-activerecords-create-tables/176033>\
**Category:** Rails\
**Created:** [September 23, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033 "2009-09-23T21:33:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cristie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@cristie](https://www.ruby-forum.com/u/cristie)\
**Post date:** [September 23, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033/1 "2009-09-23T21:33:24Z")

</div>

I’ll start off by saying I am new to Ruby and Rails…

Suppose I run the following;

$ script/generate model person

which creates:

class CreatePeople \< ActiveRecord::Migration  
def self.up  
create\_table :people do |t|

```
  t.timestamps
end

```

end

def self.down  
drop\_table :people  
end  
end

I added in some code (the author instructs me to) such that it now  
reads:

class CreatePeople \< ActiveRecord::Migration  
def self.up  
create\_table :people do |t|  
t.string :name, :type, :email, :camera #ADDED IN  
t.timestamps  
end  
end

def self.down  
drop\_table :people  
end  
end

I do not understand, at a ruby level, what is going on. It appears I  
have a class (static) method called up. The first thing I am doing is  
calling Migration’s create\_table method. This leads to question 1:

1:) Migration does not have create\_table method. How is Ruby finding  
create\_table?

Now the create\_table method appears to accept two parameters. The first  
being a symbol, and the second being a code block.

I am assuming that the only thing obtainable from this code block is the  
last line t.timestamps, as the last line is returned in ruby.

So question number two:

2: What does this line even do?  
t.string :name, :type, :email, :camera #ADDED IN

What is t being passed in? why no comma between t.string and :name.

And my final question…

How come I cannot write the code as follows (Aptana will not compile  
it)?  
def self.up  
create\_table (:people,{|t|  
t.string :name, :type, :email, :camera  
t.timestamps  
})  
end

BTW as I hunt I do see this in Migration:

def method\_missing(method, \*arguments, &block)

It is taunting me.

Feel free to respond to me like I am four. You could try to insult me  
but you would fail 🙂

Thanks,

Cris

---

<div class="post-metadata">

**Author:** ![cristie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@cristie](https://www.ruby-forum.com/u/cristie)\
**Post date:** [September 23, 2009, 10:18pm UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033/2 "2009-09-23T22:18:17Z")

</div>

Cris S. wrote:

> I’ll start off by saying I am new to Ruby and Rails…

You might find it helpful to read about Ruby’s object model in general.  
It’s subtly different from those of most other OO languages.

> Suppose I run the following;
> 
> $ script/generate model person
> 
> which creates:
> 
> class CreatePeople \< ActiveRecord::Migration  
> def self.up  
> create\_table :people do |t|
> 
> ```
> t.timestamps
> end
> 
> ```
> 
> end
> 
> def self.down  
> drop\_table :people  
> end  
> end
> 
> I added in some code (the author instructs me to) such that it now  
> reads:
> 
> class CreatePeople \< ActiveRecord::Migration  
> def self.up  
> create\_table :people do |t|  
> t.string :name, :type, :email, :camera #ADDED IN  
> t.timestamps  
> end  
> end
> 
> def self.down  
> drop\_table :people  
> end  
> end
> 
> I do not understand, at a ruby level, what is going on. It appears I  
> have a class (static) method called up.

Correct.

> The first thing I am doing is  
> calling Migration’s create\_table method. This leads to question 1:
> 
> 1:) Migration does not have create\_table method.

You’re right. But the DB connection adapters do.

> How is Ruby finding  
> create\_table?

Presumably by delegating to the connection adapter, likely by means of  
method\_missing.

> Now the create\_table method appears to accept two parameters. The first  
> being a symbol, and the second being a code block.
> 
> I am assuming that the only thing obtainable from this code block is the  
> last line t.timestamps, as the last line is returned in ruby.
> 
> So question number two:
> 
> 2: What does this line even do?  
> t.string :name, :type, :email, :camera #ADDED IN
> 
> What is t being passed in?

A block argument.

> why no comma between t.string and :name.

Because string is the name of the method being called on t , while :name  
is its first argument. With parentheses, it would be t.string(:name,  
:and\_so\_on) , but in Ruby, you can omit the parentheses when it would  
not be ambiguous.

> And my final question…
> 
> How come I cannot write the code as follows (Aptana will not compile  
> it)?  
> def self.up  
> create\_table (:people,{|t|  
> t.string :name, :type, :email, :camera  
> t.timestamps  
> })  
> end

Because you’ve got your syntax wrong. The braces aren’t correct In this  
context (this isn’t JavaScript!) and parens don’t go around blocks  
passed to functions.

Aptana isn’t doing any compilation for you, BTW. (And on an unrelated  
note, the sooner you stop using an IDE for Rails, the better. I  
reccomend a good editor like KomodoEdit instead.)

> BTW as I hunt I do see this in Migration:
> 
> def method\_missing(method, \*arguments, &block)
> 
> It is taunting me.

What’s taunting you? Go learn about method\_missing and how it works.  
It’s an important Ruby concept.

> Feel free to respond to me like I am four. You could try to insult me  
> but you would fail 🙂

I think you can answer many of your questions by looking at the Rails  
source and the remainder by reading Programming Ruby.

> Thanks,
> 
> Cris

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![cristie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@cristie](https://www.ruby-forum.com/u/cristie)\
**Post date:** [September 24, 2009, 2:14am UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033/3 "2009-09-24T02:14:08Z")

</div>

Marnen Laibow-Koser wrote:

> Cris S. wrote:  
> […]
> 
> > How come I cannot write the code as follows (Aptana will not compile  
> > it)?  
> > def self.up  
> > create\_table (:people,{|t|  
> > t.string :name, :type, :email, :camera  
> > t.timestamps  
> > })  
> > end
> 
> Because you’ve got your syntax wrong. The braces aren’t correct In this  
> context (this isn’t JavaScript!) and parens don’t go around blocks  
> passed to functions.  
> […]

On second thought, the braces are probably OK (although it’s more common  
to use do…end for multiline blocks and braces for single-line ones).  
The bigger problem is the parentheses. If you’re going to use them,  
then the closing parenthesis goes _before_ the beginning of the block.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![cristie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@cristie](https://www.ruby-forum.com/u/cristie)\
**Post date:** [September 25, 2009, 2:39am UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033/4 "2009-09-25T02:39:13Z")

</div>

Marnen,

Thanks! You answered my questions perfectly!!!

Thanks,

Cris

Marnen Laibow-Koser wrote:

> Marnen Laibow-Koser wrote:
> 
> > Cris S. wrote:  
> > […]
> > 
> > > How come I cannot write the code as follows (Aptana will not compile  
> > > it)?  
> > > def self.up  
> > > create\_table (:people,{|t|  
> > > t.string :name, :type, :email, :camera  
> > > t.timestamps  
> > > })  
> > > end
> > 
> > Because you’ve got your syntax wrong. The braces aren’t correct In this  
> > context (this isn’t JavaScript!) and parens don’t go around blocks  
> > passed to functions.  
> > […]
> 
> On second thought, the braces are probably OK (although it’s more common  
> to use do…end for multiline blocks and braces for single-line ones).  
> The bigger problem is the parentheses. If you’re going to use them,  
> then the closing parenthesis goes _before_ the beginning of the block.
> 
> ## Best,
> 
> Marnen Laibow-Koser  
> [http://www.marnen.org](http://www.marnen.org)  
> removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![cristie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@cristie](https://www.ruby-forum.com/u/cristie)\
**Post date:** [September 25, 2009, 2:45am UTC](https://www.ruby-forum.com/t/how-activerecords-create-tables/176033/5 "2009-09-25T02:45:50Z")

</div>

Oh and this does work, not around the block as you said:

def self.up  
create\_table (:people) { |t|  
t.string :name, :type, :email, :camera  
t.timestamps  
}  
end

Thanks again!

Cris S. wrote:

> Marnen,
> 
> Thanks! You answered my questions perfectly!!!
> 
> Thanks,
> 
> Cris
> 
> Marnen Laibow-Koser wrote:
> 
> > Marnen Laibow-Koser wrote:
> > 
> > > Cris S. wrote:  
> > > […]
> > > 
> > > > How come I cannot write the code as follows (Aptana will not compile  
> > > > it)?  
> > > > def self.up  
> > > > create\_table (:people,{|t|  
> > > > t.string :name, :type, :email, :camera  
> > > > t.timestamps  
> > > > })  
> > > > end
> > > 
> > > Because you’ve got your syntax wrong. The braces aren’t correct In this  
> > > context (this isn’t JavaScript!) and parens don’t go around blocks  
> > > passed to functions.  
> > > […]
> > 
> > On second thought, the braces are probably OK (although it’s more common  
> > to use do…end for multiline blocks and braces for single-line ones).  
> > The bigger problem is the parentheses. If you’re going to use them,  
> > then the closing parenthesis goes _before_ the beginning of the block.
> > 
> > ## Best,
> > 
> > Marnen Laibow-Koser  
> > [http://www.marnen.org](http://www.marnen.org)  
> > removed\_email\_address@domain.invalid
