%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start off with some headers
Title: Taller de Ruby/Rails
Author: DevChix Uruguay y Amigos
Generator: text
%css
body {
font-family: ‘Helvetica Neue’, Helvetica, sans-serif;
}
.slide h2 {
font-size: 24pt;
}
table td {
padding: .5em;
border: 1px solid #ccc;
}
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start Presentation
Buenos Días!
SKIP
Algo que decir que quiere ser una nota privada.
END
- Devchix : @devchix y www.devchix.com
- RailsBridge en la comunidad Ruby/Rails
- PyStar en la comunidad Python
- En Montevideo gente de Cubox, WyeWorks y Moove-it
- 9:00 Presentaciones
- 9:30 – 13:00 Instalación del ambiente de trabajo
- 10:30 -11:30 Introducción a Ruby
- 11:30 -12:00 Ruby Koans
- 12:00 -1:00 Almuerzo
- 1:00 – Rails parte 1
- 2:45 -3:00 Descanso
- 3:00 -4:30 Rails parte 2
- 4:30 Y ahora? Contribuyendo con Rails
- Ruby
- Instalando el ambiente de trabajo
- Sintaxis y operaciones simples en Ruby
- Objetos, clases, modulos y métodos
- Testing en Ruby
- Bloques y estructuras de control
- Expresiones regulares
- Excepciones
- Una introducción a Rails
- Un tour desde la consola de Rails
- Modelos
- Vistas
- Controladores
- Originado en Japón a mediados de los 90, su creador es Yukihiro “Matz” Matsumoto. Está inspirado en Perl, Lisp entre otros lenguajes
- “I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python. That’s why I decided to design my own language”.
- Ruby es un lenguaje
- dinamico
- reflexivo
- orientado a objetos
- open source
- Hay diferentes implementaciones del lenguaje
- MRI (mat’z ruby interpreter) es la referencia que hay de Ruby. Está escrito en C
- JRuby es una implementación hecha en Java
- IronRuby corre sobre .NET. Es desarrollado por Microsoft bajo la Apache License.
- Rubinius esta hecho en Ruby
- Versiones
- 1.8.7
- 1.9.2 <— recomendada
- “Lenguajes de Programación deben sentirse natural para los programadores.”
- La comunidad de Ruby en Montevideo está creciendo
- Tiene RubyGems que es el sistema usado para empaquetar y distribuir código Ruby
- Rails es un web framework bastante popular construido sobre Ruby
- En 10 años se han agregado una gran cantidad de clases y modulos nativos al lenguaje.
- Tiene buenas herramientas para testing como RSpec y Cucumber.
- Todos se sienten comodos manejando una terminal?
- En linux ó Mac (tener el sistema actualizado e instalado curl y git)
- RVM: Te permite manejar multiples interpretes de Ruby en la misma máquina y fácilmente cambiar entre versiones.
bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
- Seguir las instrucciones para agregar rvm al .bashrc
source $HOME/.rvm/scripts/rvm
rvm notes
- RVM: Te permite manejar multiples interpretes de Ruby en la misma máquina y fácilmente cambiar entre versiones.
- En Windows hay que instalar primero Ruby, a no ser que usen RailsInstaller que ya instala todo
- Ruby: Vamos a usar la version 1.9.2 y el interprete MRI
- Ir a http://rubyinstaller.org y descargar la versión de Ruby mediante el botón Download.
- Ejecutarla y comenzar la intalación
- Mediante Rails installer
- Ir a http://railsinstaller.org y descargar el paquete mediante el botón Download the kit.
- Ruby: Vamos a usar la version 1.9.2 y el interprete MRI
- En Linux ó Mac
- Ruby: para este taller usaremos mri y la versión 1.9.2
rvm install 1.9.2
- mirar rvm help para ver que más se puede hacer
- Ruby: para este taller usaremos mri y la versión 1.9.2
- En Windows
- PIK: Te permite manejar multiples interpretes de Ruby en la misma máquina y fácilmente cambiar entre versiones.
- Descargar la última versión http://github.com/vertiginous/pik/downloads
- Seguir los pasos de la instalación
- Deslogueate o reinicia windows para integrar pik al ambiente.
- En una terminal
pik add
pik list
pik use 192
ruby -v
- Ó Ruby Installer: Un ejecutable que instala Ruby y Ruby Gems
- Descargar la ultima verisón de http://rubyinstaller.org
- Seguir los pasos de la instalación
- Instalar pik mediante @gem install pik
- PIK: Te permite manejar multiples interpretes de Ruby en la misma máquina y fácilmente cambiar entre versiones.
- Instalar Ruby Gems
- En Linux
- @apt-get install rubygems
- En Windows RubyInstaller ya viene con Ruby Gems
- En Linux
- Rails: Vamos a usar la version 3.1
- @gem install rails
- Editores: Trabajen en el que se sientan más comodos
- VIM
- Textmate
- Emacs
- Gedit
- Eclipse
- NetBeans
- RubyMine
Abrir una terminal y ejecutar irb.
Jugar un poco:
1
4 + 3
"hat"
[1, 2, 3, "happy"].each { |i| puts i }
>>
es donde ingresas comandos y en =>
va a aparecer la respuesta.
irb tiene un historial de comandos. Usen las flechitas para navegarlo.
% TODO more table
Integers | 1 , 2 , 3 |
Strings | "chicken" |
Booleans | true , false |
Symbols | :chicken |
Arrays | [1, 7, "cake"] |
Hashes | {:chicken => "chicken", :sillyexample => :chicken} |
En Ruby casi todo es un objeto. A un objeto se le puede enviar los mensajes a los que el objeto puede responder. A grandes rasgos a esto le llamamos “duck typing”. Si un objeto camina como un pato y habla como un pato, entonces el interprete lo trata como un pato.
Juega con la terminal!
% Esto no está muy claro <<—- MIRAR COMO INCLUIR LA EIGENCLASS
% Las estructuras de control no son objetos ni mensajes que se envian a otros objetos, por eso la aclaracion de casi todo, en algún que otro lenguaje esto si se cumple.
% La definicion de Duck Typing no es “El tipo del objeto es definido por lo que el objeto puede hacer”.
% Duck Typing indica que a un objeto le podemos enviar los mensajes a los que el objeto puede responder, sin importar el tipo del objeto. Comunmente se dice: “Si camina como un pato y habla como un pato, entonces es un pato”
% Si por tipo del objeto entendemos “Lo que el objeto puede hacer”, entonces cabe la pregunta “Que es lo que puede hacer el objeto?”, la respuesta sería: “Todo lo que hace es recibir mensajes, los mensajes que puede recibir estan determinados por los métodos del objeto”. Quién determina los métodos del objeto? La clase del objeto.
% Cuál es la clase de un objeto? Depende, puede ser la clase a partir de la cual se creó el objeto, o la clase Singleton del objeto (clase Eigen, es una clase anónima).
% O sea que el tipo de un objeto es la clase del objeto.
% Ejemplos:
% bc. irb> names = [‘jessie’, ‘john’]
% irb> numbers = [1, 2, 3, 4]
% irb> def numbers.multiply
% irb> inject(:*)
% irb> end
% La clase de names
es Array
y no contiene el método multiply
% La clase de numbers
es una clase Singleton
, única al objeto, que contiene la definición del método multiply
.
- En Java
min = Math.abs(num)
- En Ruby
postive = num.abs
- En C
strlen(name)
- En Ruby
name.lenght
Le enviamos un mensaje al propio objeto. Y lo mismo aplica a toods los objetos en Ruby.
En Ruby, NIL es un objeto que representa ausencia de valor.
2 + 2 |
4 |
3 * 3 |
9 |
"chicken".reverse |
"nekcihc" |
"chicken".length |
7 |
2 + 2 == 4 |
true |
2 + 2 == 5 |
false |
[1, 2, 3].include?(2) |
true |
Y que es lo que hace "chicken".reverse.length
?
Y "puppy".include?("p")
?
Algo que Ruby hace con strings entre comillas dobles es interpolacion de expresiones. Es decir, dentro de un string la secuencia #{expression}
es reemplazada por el valor de la expresión.
Por ejemplo, prueba
@"Nuestro array es #{[1,2,3]}"@
Ó
var = [1,2,3,4,5,6]
"Nuestro array es #{var}"
Las variables son implícitas y declaradas.
Qué pasa en cada paso?
thing = "chicken"
thing
thing.reverse
thing
thing = thing.reverse
Intenten.
awesome_list = [5,2,1,8]
awesome_list.sort!
awesome_list
Como paso esto? Acciones que terminen con un !
“cambian” los datos!
Esto es una convención de Ruby, pero una buena a seguir.
- locales: comienzan con minúscula o guión bajo
- globales: comienzan con $
- de instancia: comienzan con @
- de clase: comienzan con @@
- de más de una palabra se escriben con guión bajo. Ej. user_name
- constantes en mayúscula
Hay tres lugares donde el alcance cambia: las definiciones de clases (class
), las definiciones de modulos (module
) y los métodos (def
)
Son etiquetas que no hay que pre-declarar y que son únicas. Empieza con :
y es seguido por un nombre. Ruby garantiza que en cualquier parte del programa en donde aparezca el símbolo va a tener el mismo valor. Son usualmente usados como llaves de un hash.
Por ejemplo:
:norte
:sur
- También es un tipo nativo del lenguaje.
- Al igual que los arrays son colecciones indexadas.
- Las llaves de los arrays deben ser integer pero los hashes pueden tener cualquier objeto como llave.
- Pueden contener diferentes tipos de elemento en el mismo array/hash.
- Por defecto el valor para nil en un hash es false. Se puede cambiar al crear el hash.
- En Ruby 1.9 se introduce un nuevo sintaxis para hashes
frutas_color = {
naranja: "naranja",
frutilla: "rojo",
banana: "amarillo
}
frutas_color[:frutilla]
produce "rojo"
También conocidos como Map, Associative Array, Dictionary, Key/Value Pair Store
Consideremos un sistema de rating de libros:
- Usamos valores numericos 0-5 para valorar un libro que hemos leido.
:not_rated
va a representar un libro que aún no ha sido valorado.- Vamos a guardar los datos en un hash.
Crea un hash y agregale algunos libros, por ejemplo:
books = { "Left Hand of Darkness" => 5,
"The Word for World Is Forest" => 5,
"Nevermind the Pollacks" => 0,
"Only Revolutions" => :not_rated
}
Vamos a obtener el rating de un libro en particular con
books["Left Hand of Darkness"]
También podemos guardar valores con
books["Only Revolutions"] = 3
Agregamos un libro de la misma forma
books["White Teeth"] = 4
Y con books
vemos todo el hash
Jueguen con el hash en irb
40.reverse
Qué pasa?
Ruby dijo NoMethodError: undefined method `reverse' for 40:Fixnum
Significa que reverse
no es un método que podamos aplicar al número 40
Los métodos son invocados al enviarles un mensaje al objeto. El mensaje contiene el nombre del método asi como cualquier parametro que este necesite.
Si quieren ver los métodos de un objeto pueden escribir 40.methods.sort
Nuevamente, todo lo que manipulas en Ruby es un objeto y los resultados de esas manipulaciones tambien son objetos. Cada objeto tiene un identificador único.
Un objeto son los datos asi como tambien los métodos que se le puede aplicar.
Un objeto es una estructura con identidad, estado y un comportamiento definidos.
Como averiguamos la clase origen de un objeto? Sólo hay que preguntarle!
40.class
Aprendamos la sintaxis mediante un ejemplo:
class Counter
end
Qué podemos hacer con Counter
?
c = Counter.new
% Step 1 %
Aprendemos la sintaxis mediante un ejemplo:
class Counter
attr_accessor :value
end
Ahora intentemos
c = Counter.new
c.value
c.value = 10
c.value
Qué pasa? Que es lo que hace attr_accessor :value
?
Aprendemos la sintaxis mediante un ejemplo:
class Counter attr_accessor :value
def initialize @value = 0 end end
Nuevamente
c = Counter.new
c.value
initialize
le da instrucciones a new
de como crear un objeto
% Step 2 %
Aprendamos la sintaxis mediante un ejemplo:
class Counter attr_accessor :value
def initialize @value = 0 end
def increment @value = @value + 1 end end
Estas definiciones de un método son equivalentes:
def increment x x + 1 end
def increment(x) return x + 1; end
def increment(x); x + 1; end
Usemos nuestra clase Counter:
count = Counter.new
count.increment
count.increment
count.value
count.class
count.methods.sort
count.respond_to?(:increment)
Vamos a agregar un método Counter.increment_by
que tome un argumento por el cual incrementar el contador.
No hay que empezar desde cero; podemos sólo abrir la clase
% Sería bueno aclarar que abrir una clase es una mala práctica, que si bien es útil y rapido en algunos casos, existen otras prácticas mejores para agregar nuevo comportamiento a una clase.
class Counter
def increment_by(n) # fill in here end
end
Prueba el código que escribiste:
c = Counter.new
c.increment_by(5)
c.value
También se puede agregar métodos a clases ya existentes:
class String
def chicken?
self == "chicken"
end
end
"chicken".chicken?
"puppy".chicken?
self
es una forma de referirse al objeto del cual el método se esta llamando.
En "puppy".chicken?
, self
es "puppy"
.
Si aún no lo han hecho, escriban la clase Counter en su editor favorito y guardenlo en disco. Levantemoslo en la consola de ruby.
class Counter
attr_accessor :value
def initialize
@value = 0
end
def increment
@value = @value + 1
end
def increment_by(n)
@value = @value + n
end
En la consola: require 'path_to_your_file'
Un módulo es básicamente una clase que no puede ser instanciada.
Ruby tiene tres niveles de protección para constantes y mteodos de clase y modulo.
- public. Accesible para todo el mundo.
- protected. Puede ser sólo invocado por objetos la clase definida y sus subclases.
- private. Puede ser solo llamado en una forma funcional (con un self implicito). Por lo tanto métodos privados solo pueden ser llamados en la clase definida y por los ancestros y descendientes de la clase, pero solo dentro del mismo objeto.
Automatizar cualquier tarea que se pueda hacer más de una vez es una sabia decisión.
- no tener que pasar horas buscando un bug en el código que se escribio hace meses
- escribir codigo mas robusto y de mejor calidad
- el código se hace más mantenible
- más productividad a largo plazo sobre la aplicación
Ahora escribiremos una clase para testearlo automáticamente.
require 'test/unit'
require 'counter'
class TestCounter < Test::Unit::TestCase
def test_increment
assert_equal(1, Counter.new().increment())
end
end
Escribanlo en un archivo test_counter.rb y ejecutenlo.
Escribir un test para increment_by.
Agregar un método a String que devuelva si un string es palindromo o no.
Un palindromo es cualquier cadena de caracteres que se lea igual de adelante para atras que de atras para adelante.
Para empezar tipear lo siguiente en la linea de comandos:
class String
def palindrome?
y terminarlo! Pruebenlo con "abba".palindrome?
y "puppy".palindrome?
http://rubydoc.info/stdlib/core/
Otras son: Array, Enumerable, Fixnum, Float, Hash, NilClass, String, Time
Algunos métodos también pueden tener asociados bloques como si fueran parametros.
list.each {|p| code}
corre code
en cada elemento de list
list = [1,2,3,4]
list.each { |n| puts (n + 1) }
- Un bloque es un pedazo de código asociado a un contexto de variables.
- Puede tener dos sintaxis
- Cuando es sólo una linea
{ |arg1, arg2, ..| code }
{ |v| v.palindrome? }
{ |x, y| x * y }
- Cuando es más de una linea
bc.. do |arg|
code
end
- Cuando es sólo una linea
Para nuestro ejemplo de los libros.
reviews = Hash.new(0)
books.values.each { |rate| reviews[rate] = reviews[rate] + 1 }
reviews
Qué contiene reviews
?
reviews[5]
Y en caso que el bloque tenga más de una linea
reviews = Hash.new(0)
books.values.each do |rate|
reviews[rate] = reviews[rate] + 1
# more code can go here...
end
Se pueden usar bloques para implementar callbacks, para pasar pedazos de código e implementar iteradores.
Por ejemplo,
def call_block
puts "Comienzo del método"
yield
yield
puts "Fin del método"
end
call_block { puts "En el bloque" }
produce:
Comienzo del método
En el bloque
En el bloque
Fin del método
yield invoca al bloque asociado con la llamada al método que lo contiene
Los bloques no son objetos pero pueden ser convertidos en objectos mediante la clase Proc. Hay varias formas de convertir un bloque en un objeto Proc:
- Pasando un bloque a un método cuyo último parametro es prefijado con un ampersand.
def método(p1, p2, &bloque)
puts bloque.inspect
end
método(1,2) { "un bloque" }
método(3,4)
- Llamando Proc.new
Proc.new{ "un bloque" }
- Llamando a el método Object#lambda asocia un bloque con la llamada lambda{ “un bloque” }
- En 1.9 usando la sintaxis
lam =->(p1,p2) {p1 + p2}
lam.call(4,3)
Diferencias entre Procs y Lambdas:
- Return keyword.
- En un lambda, return retorna desde el lambda.
- En un proc el return retorna desde el alcance donde el proc fue definido.
- Argumentos.
- Si se llama a un lambda con una aridad incorrecta entonces falla con ArgumentError.
- Los Proc son más flexibles y toman la cantidad de argumentos necesaria llenando los no dados con nil.
Ruby provee las clasicas estructuras de control como los if y while loops.
Sintaxis if
if true
1
else
2
end
ó
código if true
Sintaxis while
while true
do some code
end
ó
some_code while true
3.times{ puts "Hola mundo!" }
5.downto(1){|i| puts "Cuenta regresiva #{i}."}
animals = ["gato", "perro", "caballo"]
animals.each do |animal|
puts "Tenemos un #{animal}."
end
my_hash = {:type => "cat",
:name => "Beckett",
:breed => "alley cat"}
my_hash.each do |key, value|
puts "My #{key.to_s} is #{value}"
end
my_hash.each_pair{|k,v| puts "key: #{k} con su valor #{v}"}
- Ruby las tiene nativo en el lenguaje
- La sintaxis es /pattern/
- Una expresión regular también es un objeto. Son instancias de la clase Regexp
Por ejemplo, /P(ython|erl)/ matchea los strings que contengan Python o Perl
Información de una excepción viene encapsulada en un objeto de clase Exception o alguno de sus “hijos”.
Para manejar excepciones:
begin # .. procesar rescue # .. manejar el error ensure # ..codigo que siempre se ejecuta (por ejemplo f.close para un archivo f) end
Para levantar excepciones con Object#raise :
raise ArgumentError, "Name too big", caller
Son ejercicios para aprender/practicar Ruby. Aconsejables para cualquier nivel. Tiene también ejercicios sobre metaprogramación.
Descargarlos desde “http://rubykoans.com/”http://rubykoans.com
- Rails es un framework para construir aplicaciones web
- Está estructurado usando una arquitectura llamada MVC: Model-View-Controller
- MVC separa diferentes partes de la lógica de la aplicación en secciones en función de para que son usadas.
- Convenciones sobre configuraciones
- Crear una aplicación Web implica tomar muchas decisiones.
- Rails tiene una opinión sobre cómo habria que desarrollar aplicaciones web.
- Esto hace que algunas las tareas que sigan sus convenciones sean muy sencillas (y las que no sigan las convenciones de Rails lleven un poco más de trabajo)
- Comunidad y Herramientas
Existe una comunidad muy activa entorno a Rails y podemos aprovecharla para consultar y usar las herramientas desarrolladas.
Escribir en una consola:
cd microrant
bundle install
rake db:migrate
rails server
- Abrir http://localhost:3000 en tu navegador
- Twitter?
- 10 caracteres para expresar tu ira
- Actividades basicas: create, read, update, delete (CRUD)
- Ir a http://localhost:3000/users/new para crear un nuevo usuario con tu nombre
- Luego ir a /rants/new y crear un nuevo rant
- Rants también pueden ser editados y borrados!
- Qué hay detrás de escenas?
- Rails trae clases que nos permiten obtener y manipular datos fácilmente
- La lógica de la aplicación se escribe en Ruby común y corrriente, y un modulo llamado ActiveRecord hace todo el trabajo de conexión a la base de datos
Organización por defecto de Rails:
—> controllers/
—> helpers/
—> mails/
—> models/
—> views/
—> database.yml
—> routes.rb
- Cerrar el servidor Rails con Ctrl-C
rails console
- Puedes modificar los datos usando las clases
Rant
yUser
- La clase
User
tiene atributosid
yname
- La clase
Rant
tiene atributosid
,message
yuser_id
Como podemos ver un rant luego que fue creado?
r = Rant.find(1)
r.message
r.user_id
Y como podemos modificarlo?
r.message = "RANTING!"
r.save
Necesitamos guardar (save
) los cambios luego que terminamos de editarlo.
Tambien podemos modificar directamente con update_attribute(:message, "RANTING")
. Si quieren ver mas métodos, consulten la documentación de Rails.
Los modelos en Rails tienen métodos de busqueda incorporados que ayuda a obtener los registros desde la base de datos.
Rant.all
Rant.order("created_at DESC")
Rant.first
Rant.where("user_id = 1")
Rant.where(:user_id => 1)
Rant.where(:user_id => 1).order("created_at DESC")
Observa la sentencia de SQL generado con el método to_sql
Intentemos crear un nuevo Rant para user_id
1
rant = Rant.new
rant.user = User.find(1)
rant.message = "WHAT IS TH"
rant.save
No tuvimos que setearle el valor de id
al mensaje!
Esto fue automaticamente hecho por new
.
Guardamos (save
) el registro cuando terminamos, para poder crearlo, al igual que cuando estabamos editándolo.
Hay una mejor manera de crear un rant
User.find(1).rants.create(:message => "E POINT!?")
De esta forma no tenemos que usar save para guardar pues usamos create
—quien combina new
y save
en un sólo paso.
Abrir los archivos user.rb y rant.rb en el directorio models/
class Rant < ActiveRecord::Base belongs_to :user
validates :user, :presence => true validates :message, :presence => true, :length => { :maximum => 10 } end
class User < ActiveRecord::Base has_many :rants
validates :name, :presence => true end
Algunas personas están escribiendo rants en minúsculas!
Vamos a escribir un método para convertir todos los rants a mayúsuculas.
Primero encuentren el archivo rant.rb en el directorio de modelos de Rails.
class Rant < ActiveRecord::Base
before_save :convert_message_to_uppercase
def convert_message_to_uppercase
...
Rails tiene muchas extensiones a las clases de Ruby para hacer que las tareas comunes sean sencillas. Miren en http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html y encuentren el helper que necesitan para este ejercicio.
Una vez que lo hicieron prueben escribir un rant en minúsculas para ver qué pasa.
Esta vez utilicen un método de Ruby? Miren en: http://www.ruby-doc.org/core-1.9.2/String.html y busquen si hay un método de instancia que permite pasar a minúsculas un String.
Pueden querer trabajar con sus datos en algún otro formato. Vuelvan a la consola de Rails y escriban un programa que cree un hash que contenga mensajes rant junto con el nombre del usuario que lo escribió.
Como era que se creaba un Hash?
- Vimos
Hash.new
pero también se puede crear con{}
. - Intenta
new_hash = {}
El resultado debería ser algo como:
=> {"RANTING!"=>"caylee", "WTF"=>"audrey"}
Pueden usar un iterador para mostrarlo como una serie de strings formateados?
El código que aparece en before_save
usa un callback. Rails define varios callbacks que nos permiten cambiar la entrada a un modelo antes o después de acciones como save, create, update y delete.
before_save :geocode_address
after_create :notify_admins
before_validate :check_over_some_other_details
Las validaciones dan un wrapper sencillo para chequear si un atributo en particular está presente, si esta en el formato correcto u otros requerimientos antes que la aplicación guarde los datos. La aplicación de microrant ya tiene algunos de éstos. Miren en los modelos Rant
y User
para ver cuáles hemos incluído.
Pueden pensar de algunas otras validaciones que podamos querer usar? Intenten cambiar el largo de un mensaje de Rant válido.
Rails automáticamente crea vistas con contenido usando el comando scaffold
. Miren lo que tenemos en /app/views
Estos archivos usan el sistema de templating llamado ERB que convierte líneas de Ruby en la vista en HTML estático para desplegar. Una línea típica de ERB podria ser como esto:
5 + 1 = < %= 5 + 1 %>
Se vería así:
5 + 1 = 6
Documentación sobre la sintaxis de ERB: http://ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html
El sistema de scaffolding es rápido de usar, pero no siempre lindo. Nuestra lista de rants tiene al user_id
para la persona que lo dijo pero no su nombre. Cambien eso.
Ir a /app/views/rants/
y abran el archivo index.html
. Por defecto, el scaffolder hace que la vista index muestre una lista de registros relacionados al tipo del modelo. Encuentren la línea que muestra el id del usuario y cámbienla para mostrar el nombre de usuario.
Modifiquen el archivo index.html
de rants, para que muestre “No hay rants” en vez de la tabla, en caso de que no existan rants.
En la página index
de usuarios, agreguemos una columna a la tabla para mostrar cuantos rants cada persona ha escrito. ActiveRecord hace que esto sea muy fácil con un método llamado count
que se puede enviar a una colección de registros para obtener el count de la base de datos en vez de todos los registros. Por ejemplo User.count
o Rants.count
.
Ir a app/views/layouts/application.html
- En
application.html
está el template de la aplicación. - Esta página es la que permite tener un esquema html común a todas las paginas
- El método
yield
pasa la ejecución al template que se quiere ver - En este caso el template que hemos estado viendo es
index.html
- Crear un archivo en
app/views/layouts/users.html
y escribir:
< h1> Esto es solo para los Usuarios < /h1>
< %= yield %>
- Ejemplo de convención sobre configuración
Como sabe Rails que a que página ir cuando visitas http://localhost:3000/rants/new ?
Rails primero busca las páginas estáticas en public/ y luego ejecutan las reglas
Abrir /config/routes.rb para ver como funciona.
Observar la linea resources :users
Ejecutar rake routes
y analizar que devuelve? Como se relaciona con la linea de routes.rb
?
Ahora que hemos visto y editado modelos y vistas, vamos a ir a mirar los archivos de controladores en nuestro proyecto.
Qué hace un controlador?
- Conecta la vista y el modelo, llamando a métodos en los modelos para obtener los datos necesitados en la vista y permitiendote acceder parametros de entrada como los de un formulario.
- Responde al request HTTP del navegador y renderea el tipo pedido de salida (en nuestros scaffolds es html o xml pero otros como json pueden ser facilmente agregandos — API instantanea!)
- También en el controlador es donde se deberia agregar los controles de acceso, como por ejemplo solo permitir que el usuario que escribio el rant pueda eliminarlo.
Modificar el código para no permitir escribir más de 3 rants por dia.
- Agregar el siguiente código en el
users_controller.rb
de la carpetaapp/controllers
bc..
before_filter :no_quejarse_demasiado, :only => [:new, :create]
En app/views/layouts/application.html.erb
agregar arriba de yield
bc..
< %= flash[:notice] %>
- Ir al directorio donde puedas crear una aplicación nueva de Rails
- Correr
rails new betterrant
- Ir al directorio creado
cd betterrant
bundle install
rails generate scaffold User name:string
rails generate scaffold Rant user_id:integer message:string
rake db:migrate
En este momento puedes iniciar el servidor y mirar que hay
- Hemos visto lo básico del lenguaje Ruby
- Si quieren repasarlo, Try Ruby es una aplicación web para jugar con Ruby
% Algo más sobre lo que vimos %
- Hemos aprendido sobre una pequeña aplicación Rails: microrants
- Un tutorial que pueden mirar es Rails For Zombies
- Y en más detalle pueden encontrar Ruby Guides
- ActiveRecord nos permite manipular datos persistidos como si fueran objetos comunes
- Los archivos .erb nos permiten integrar el código Ruby con html
- Scaffolding nos da una forma de automatizar el comienzo de un proyecto Rails
- PickAxe es un clásico entre los libros para aprender Ruby. Pueden encontrarlo en http://pragprog.com
- Web RubyLang para ver lo último de Ruby: http://www.ruby-lang.org
- La documentación de Ruby http://www.ruby-doc.org
- Meta Koans http://www.rubyquiz.com/quiz67.html
- Participa en el grupo de Ruby de Uruguay. Comparte lista de correo con los usuarios de Ruby de América del Sur. http://rubysur.org/
- Otras listas de correo
- [email protected] (en ingles)
- [email protected] (en ingles) sobre documentación
- [email protected] (en ingles) sobre implemantación del core de ruby
- [email protected] (en ingles) para desarrolladores de ruby
- RubyConf Uruguay 2011 el próximo fin de semana.
- Reportar Bugs en Ruby
- El tracking system está en http://redmine.ruby-lang.org
- Antes de reportarlo navega los bugs ya reportados para ver si tu bug ya existe. También proba nuevas versiones de ruby por si eso lo soluciona.
- También es una buena idea enviar una pregunta sobre el bug a la lista de correo ruby-talk.
- Cuando envias un bug es una buena idea incluir el resultado de ejecutar ruby -v, el sistema operativo y además la problematica del código.
- Ayudar con la documentación
- Hacer traducción
- Mejorar la documentación
- Hay un sistema llamado RDoc
- ri es un visor en la consola para esa misma documentación. Tipea ri ClassName para encontrar la documentación de esa clase