small medium large xlarge

Generic-user-small
23 Jun 2010, 03:14
Malcolm Arnold (21 posts)

the following code:

class CreateProducts < ActiveRecord::Migration
def self.up
create_table :products do |t|
t.string :title
t.text :description
t.string :image_url
t.decimal :price, :precision => 8, :scale => 2

t.timestamps
end
end


def self.down
drop_table :products
end
end

</code> There is a blank line above t.timestamps, should this be removed or is it there with regards to a convention that I am not aware of?

Also in the text below:

Now let’s look at the same example from a Ruby perspective. A class named CreateProducts is defined, which inherits from the Migration class from the ActiveRecord module. Two class methods are defined, one named up, and the other named down. Each calls a single class method (defined in ActiveRecord:: Migration), passing it the name of the table in the form of a symbol.

The call to up also passes a block which is to be evaluated before the table is created. This block, when called, is passed an object named t which is used to accumulate a list of fields. Rails defines a number of methods on this object, methods with names which are named after common data types. These methods, when called, simply add a field definition to the ever accumulating set of names.

Possibly Recommend that is rewritten as such:

Now let’s look at the same example from a Ruby perspective. A class named CreateProducts is defined, which inherits from the Migration class from the ActiveRecord module. Two class methods are defined, one named up, and the other named down. Each calls a single class method: create_table and drop_table, respectively(as defined in ActiveRecord::Migration), passing it the name of the table in the form of the symbol :products.

The call to up also passes a block which is to be evaluated before the table is created. This block, when called, is passed an object named t which is used to accumulate a list of fields. These fields, in a form of a block, are passed back to create_table to create a table which is referenced by the symbol :products. Rails defines a number of methods on this object, methods with names which are named after common data types. These methods, when called, simply add a field definition to the ever accumulating set of names.

I AM NOT SURE if that is what happens in the 2nd paragraph but I think that is what occurs. Please let me know if that is not. Thanks Sam.

Cimg0269_pragsmall
23 Jun 2010, 06:01
Seth Arnold (22 posts)

The blank line is there by convention. (Maybe not even a strong convention, but I’m used to seeing it..)

Because the .timestamps method call has so much magic associated with it, the line should not be overlooked. (It creates two new fields in the table, which requires probably 8, maybe 16, bytes more storage per record, and introduces that much more setting and getting every time this table is accessed.)

So I’m quite happy for the space :) but if you don’t want it in your own code, don’t feel compelled to have it there.

Generic-user-small
23 Jun 2010, 14:13
Malcolm Arnold (21 posts)

Thank Seth,

That is great info to know.

Please could you look above at the 2nd Possibly Recommend and give me your feedback on how I wrote the block call. Is that correctly explaining what happens?

Cimg0269_pragsmall
24 Jun 2010, 10:17
Seth Arnold (22 posts)

Malcolm, I’m afraid that Ruby code blocks are pretty confusing until you’ve seen them for a while. (And even then, it’s easy to find examples that are really confusing..)

First, (and this might be a problem in Sam’s original :) “The call to @up@ also passes a block…”. In this case, it isn’t a call to @up@, it is a definition of the class method @up@. @up@ gets called by the framework, not in this file.

Second, when @up@ is finally called (via rake @db:migrate@) @create_table@ is executed. @create_table@ is passed a block, and when @create_table@ executes the block of code, @create_table@ passes an object to the block, which the block chooses to name @t@. (I don’t know the object’s type, but it would not be too far wrong to think of the object as type ‘table’. At least it quacks like a table..)

The object (named @t@ in the block) comes with methods named similarly to SQL datatypes. The methods, when called, give the table-object the name, and the table-object knows the type to use for that name, based on the name of the method. (Which you got dead-on, or if not dead-on, at least how I’ve always understood it. :)

@create_table@ then does something with the table-object @t@, and then the framework does something else with the results of calling the @up@ method, and at the end, you get a puppy! Or at least a new database table.

I don’t know how many objects or layers of indirection are involved in this surprisingly simple-looking piece of code. I do know that it is still more pleasant to use this than writing SQL DDLs for all the database flavors by hand.

Hope this helps :) more likely it just confuses, but I can try. :)

You must be logged in to comment