Can you explain what is going on in this Ruby code?

I am learning Ruby as well as Ruby on Rails. I follow along with Learning Rails 1st Edition, but it’s hard for me to understand some of the code.

I usually work in C, C ++ or Java, so Ruby is pretty big for me.

I am currently blocked by the following code block for a database blink:

def self.up create_table :entries do |t| t.string :name t.timestamps end end 

Where did the variable t come from? What does this actually represent? Is this like "i" in a for expression (i = 0; i <5; i ++)?

Also, where: are entries defined in? (records is the name of my controller, but how does this function know about this?)

+6
ruby ruby-on-rails
source share
10 answers

:entries is a character literal, it is a literal value, like 7 or "a string" . There is nothing to define (by the way, the function does not know the name of your controller).

t is the parameter for the block that you passed to the create_tables method. What you wrote here is roughly the same:

 void anonymous_block(Table *t) { t->string("name"); t->timestamps(); } ... create_table("entries", &anonymous_block); 

in C ++. create_table calls your block and passes it the parameter you called t . I would suggest you get an introductory book for rubies, not rails. I recommend Ruby For Rails by David A. Black.

+9
source share

I will take t thing. The create_table method is similar to a C function that takes a pointer to a function that takes a single argument, a table definition object (forgive my non-existent C skills):

 void entries_table_constructor(TableDef table_definition) { table_def_add_string_column(table_definition, "name"); table_def_add_timestamps_column(table_definition); } create_table("entries", entries_table_constructor); 

But in Ruby, the definition of the function passed can be done at the time the create_table method is called. Thus, the bit between do and end is similar to the entries_table_constructor function, and the variable t is similar to the table_definition argument.

There is a big difference between function pointers in C and blocks in Ruby. In Ruby, all local variables outside the block are accessible inside the block:

 a = 10 create_table :entries do |t| puts a ... end 

Check the yield keyword in Ruby to learn how to write your own methods, such as create_table .

+2
source share

create_table is a method that accepts a lambda expression (some kind of delegate), t is the argument of the delegate. Therefore, when you execute create_table, do

 t.string :name t.timestamps 

something like pseudo code

 delegate d = funciton (t) { t.string :name t.timestamps } create_table(d); 

The direct counterparts in java are anonymous classes.

 addReturnBackListener(new Listener<EventObject>() { public void handle(EventObject e) { refreshAndShowAndList(); } }); 

": entries" is not defined at all, it's just an identifier. You can think of it as a simple string (but without wasting memory saving characters).

+1
source share

: records refer to the records table in Rails.

The migrator would know about this when the command “generate controller” was given, as I understand it (he worked professionally with Rails for a year, but was still studying).

As for | t | this is a block. To quote the Pickax book (you should immediately get a copy of either the pdf or the dead version):

Blocks can be used to determine a piece of code that should be run under some kind of transactional control. For example, you often open a file, do something with its contents, and then want the file to be closed when you are done. Although you can do this with regular code, there is an argument that the file is responsible for closing itself. We can do this with blocks.

So what happens above is that | t | it is a block that handles setting up a database connection, creating rows according to their specific types and then closing the connection.

Here is another example:

 output_string = "Let print this to file" File.open('outputfile.txt','w') do |f| #f for file f.print output_string end 

As for your iterator, yes, you can also do this:

 an_array = [1,2,3,4] an_array.each do |line|#line is the block for the elements of the array during iteration puts "Now we are at: #{line.to_s}!" end 
+1
source share

The create_table method is what is known as a block in Ruby, and t is a variable that is local to that block ( t is just a convention in Rails migration that stands for "table"). This is another more obvious Ruby block example:

 10.times do |i| print "i is #{i}" end 

:entries is a Ruby symbol, which is a kind of light string used to denote things. You could use "entries" same way. One common use of characters is to specify keys in a hash. In any case, the created table is called "records".

+1
source share

I am working on an application that also has an Entry model / entries table. Here is my migration:

 class CreateEntries < ActiveRecord::Migration def self.up create_table :entries do |t| t.string :title t.text :entry # ... end end def self.down drop_table :entries end end 

Very similar to what you are watching.

First, the first line, declaring a class called CreateEntries , which extends ActiveRecord::Migration .

Then we declare a class method called up() . A class method, unlike an instance method, refers to a class, and not to specific objects of the class. This is the keyword " self " that calls it as a class method.

Then call create_table() and passing it two things:

  • The character (" :entries "), which, as mentioned above, is similar to a string literal. This tells ActiveRecord that the created table should be called. Say you typed this code manually - forget about the generators for a minute. You typed " :entries " because you know that by the agreement tables in the Rails application they are called by multiple names, and you know that the model class that connects to this table will be called Entry .

  • We also pass the block.

A block can be enclosed in ...

 `do ... end` 

or

 `{ ... }` 

A block can take parameters enclosed by two " | " s. In this case, the create_table method passes the object of the TableDefinition class to the TableDefinition , so to answer one of your questions, t is var holding this object. Then inside the block, we call the various methods of the TableDefinition instance.

Where did the TableDefinition object TableDefinition ? This happens in the create_table() method. It contains code that creates a new TableDefinition object and "displays" it on a block ....

Source Code ActiveRecord ...

 def create_table(table_name, options = {}) table_definition = TableDefinition.new(self) table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false yield table_definition # ... end 
+1
source share

This is a typical use of blocks in Ruby. The create_table method is defined in ActiveRecord, for example:

 def create_table(table_name) table_object = some_table_setup yield(table_object) # your code block which was passed implicitly is invoked here create_table(table_object) end 
0
source share
Posts

are a reference to your input model. Each model assumes that the table name will be the same as its name, except for the table name ( http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M001653 )

t is the block parameter passed to the create_table method, see http://www.rubycentral.com/book/tut_containers.html for a better example. In this case, t means the created table ( http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M002191 )

Hope this should be enough to help you

0
source share

: entries is defined right there. The code calls the create_table method with two arguments - the desired table name and code block.

create_table will build the TableDefinition object, and then go to the code block, providing it with this object. Inside the code block, it will be called t . And finally, this code block calls some methods in t to build the columns.

0
source share

Since, based on Python, I struggled to understand this construct, I will give a non-pithonic translation of the code fragment.

First you would need to define the create_table function as this (this is just a skeleton):

 def create_table(name, setup): t = Table(name) setup(t) 

Then for each table you will create a configuration function as:

 def setup_entries(t): # <-- here is your |t|, just a function argument t.string("name") t.timestamps() 

And finally, you must create the table by calling:

 create_table("entries", setup_entries) 

This is not the case with Python. If you're curious about how to create a table in Python, you should see how django or sqlalchemy handle this.

0
source share

All Articles