
No hay versión on-line, sólo de pago
gem install rails --include-dependencies
$ rails demostracion
app/: archivos del modelo, vista, controladorcomponents/: componentes reusablesconfig/: ficheros de configuracióndb/: estructura de base de datos y dumps de datosdoc/: documentación del proyectolib/: librerías externas...
...
log/: logs de la aplicaciónpublic/: directorio con ficheros accesibles: htmls, javascripts, CSSsRakefile: script de generación de la documentación y los testsscript/: scripts de utilidadtest/: baterías de pruebasvendor/: código de tercerosapp/
controllers/
application.rbhelpers/
application_helper.rbmodels/views/
layouts/scripts/
server: script de servidor webconsole: consola irb con todo el entornogenerator: generador de códigodestroy: elimina el código generador por generatorconfig/
environment.rbenvironments/
database.ymlroutes.rb
Se puede forzar con una simple línea:
class Person < ActiveRecord::Base set_table_name "person" end
CREATE TABLE clients ( id int NOT NULL auto_increment, nif varchar(10) NOT NULL default '', razon_social varchar(128) NOT NULL default'', alias varchar(128) default '', nombre varchar(128) default '', apellido varchar(128) default '', PRIMARY KEY (id), UNIQUE KEY nif (nif) );
c = Client.new c.nif = '12 456 567' c.razon_social = 'Transportes Luis' c.save
class Client < ActiveRecord::Base end
¿Y la definición de atributos?
ActiveRecord mapea los atributos a partir de la definición de la base de datos: int a Fixnum; date a Date; char, varchar, string a String;...ActiveRecord es utilizar id como clave primaria
class Client < ActiveRecord::Base set_primary_key 'nif' end
scaffoldingnew y savecreate
c = Client.new
c.nif = '12 456 567'
c.razon_social = 'Transportes Luis'
c.save
c = Client.create ( :nombre => 'Fernando',
:direccion => 'Plaza Castilla', .... ,
:cargo => 'programador' )
find y derivados: find_all y find_by_sql
client = Client.find(3)
clients = Client.find(:all, :conditions => 'ciudad = Madrid',
:order => 'nombre ASC',
:limit => 10)
client = Client.find(:first, :conditions => 'ciudad = Madrid',
:order => 'nombre DESC')
clients = Client.find_by_sql("select * from clients
where num_telefono like '91%'")
update y update_all
client = Client.update(4, :nombre => 'Fernando A.',
:num_fax => '14343343')
clients = Client.update_all("descuento = 1.1*descuento",
"ciudad = 'madrid'")
delete y delete_alldestroy y destroy_alldelete llaman directamente a la base de datos mientras que los destroy lo hacen
a través del ActiveRecord, asegurándose que se cumple la lógica de la aplicación
Client.delete(4)
Client.delete_all("ciudad = 'madrid'")
ActiveRecord soporta la definición de relaciones entre los modelos
CREATE TABLE `proposals` ( `id` int NOT NULL auto_increment, `client_id` int NOT NULL default '0', ...
belongs_to y has_onebelongs_to: define una relación de parentescohas_one: define una relación de inclusión con una única instancia
class Contract < ActiveRecord::Base belongs_to :proposal end class Proposal < ActiveRecord::Base has_one :contract end p = Proposal.new p.contract = Contract.new...
belongs_to y has_manybelongs_to: define una relación de parentescohas_many: define una relación de inclusión con múltiples instancias
class Client < ActiveRecord::Base
has_many :proposals
end
class Proposal < ActiveRecord::Base
belongs_to :client
end
c = Client.find(3)
c.proposals.each { |proposal| print proposal.estado
if proposal.estado == 'Aceptada' }
has_and_belongs_to_many
class Client < ActiveRecord::Base has_and_belongs_to_many :proposals end class Proposal < ActiveRecord::Base has_and_belongs_to_many :clients end
CREATE TABLE clients_proposals (
client_id int NOT NULL auto_increment,
proposal_id int NOT NULL auto_increment,
PRIMARY KEY (client_id, proposal_id)
)
ActiveRecord incorpora una serie de validadores de los datos del modelo.
class Client < ActiveRecord::Base has_many :proposals validates_length_of :codigo_postal, :is => 5 validates_presence_of :nif, :razon_social end
validates_acceptance_of: comprueba que un checkbox está marcadovalidates_associated: comprueba que haya una relación entre objetosvalidates_confirmation_of: comprueba que dos campos tienen el mismo contenidovalidates_each: comprueba uno o más atributos utilizando un bloquevalidates_exclusion_of: comprueba que el atributo no está entre esos valoresvalidates_inclusion_of: comprueba que el atributo está entre esos valoresvalidates_format_of: comprueba que el formato es el indicadovalidates_length_of: comprueba que la longitud del campo sea la correctavalidates_numericality_of: comprueba que el valor sea de tipo numéricovalidates_presence_of: comprueba que el valor no sea nulovalidates_uniqueness_of: comprueba que el valor sea único
class Client < ActiveRecord::Base
validates_format_of :longitud , :with => /^\d+(cm|px|em)/
validates_inclusion_of :estado,
:in => %w{Aceptada Recibida}
end
ActionController, junto con el ActionView, forman el ActionPackActionController coordina modelo y vista, encargándose de la lógica del proceso
http://tuapp.com/clients/list
app/controllers/clients_controller.rb
def list
@clients = Client.find(:all)
end
app/views/clients/list.rhtml
... <% @clients.each do |client| %> <td><%= client.name %></td> <% end %> ...
ActionController asocia cada método a una vistarender(:action => :index): renderiza la plantilla index.rhtml render(:file => path): renderiza la plantilla indicada en el path cadena = render_to_string(:action => 'list'): renderiza la plantilla indicada en la cadena
def create
@client = Client.new(params[:client])
if @client.save
redirect_to :action => 'list'
else
render :action => 'new'
end
redirect_to(:action => 'list'): redirige a la acción list
def create
@client = Client.new(params[:client])
if @client.save
redirect_to :action => 'list'
else
render :action => 'new'
end
método new » vista new » método create
def new
@client = Client.new
end
método new » vista new » método create
<form action="/clients/create" method="post"> <p><label for="client_nif">Nif</label><br/> <input id="client_nif" name="client[nif]" size="30" type="text" value="" /></p> <p><label for="client_razon_social">Razón social</label><br/> <input id="client_razon_social" name="client[razon_social]" size="30" type="text" value="" /></p> <input name="commit" type="submit" value="Create" /> </form>
método new » vista new » método create
def create
@client = Client.new(params[:client])
if @client.save
flash[:notice] = 'Client was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
params es un objeto de tipo Hash que se utiliza para pasar parámetros entre vista y controlador.Después de la llamada a Client.new
params = { 'client' => {:nombre => 'Luis',
:telefono => '914562123',
:nif => '12345323N' },
'action' => 'create' ,
'controller' => 'clients' }
params[:client]
params[:action]
params[:controller]
routing para saber quién ha de resolver cada peticiónroutes.rb
routes.rb
map.connect ':username/contacto', :controller => 'users', :action =>'contact' map.connect 'users/:action/:id', :username=>'ap', :controller => 'users' map.connect 'ver/*nicetitles', :username=>'ap', :controller => 'pageposts', :action => 'route' map.connect 'programa/:year/:month/:day/:id', :username => 'ap', :controller => 'programmeposts', :action => 'post'
routes.rb
map.programa 'programa/:year/:month/:day/:id',
:username => 'ap',
:controller => 'programmeposts',
:action => 'post'
programa_url(:year => '2005', :month => '12',
:day => '20', :id => '5')
» http://tu.url.com/programa/2005/12/20/5
flash es una variable de tipo Hash que se comparte entre controladores y vistas
def create
@client = Client.new(params[:client])
if @client.save
flash[:notice] = 'Client was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
class ClientsController < ApplicationController
before_filter :authorize, :only => [ :admin_views, :create,
:update, :delete ]
def authorize
if not session[:user_id]
flash[:notice] = "Por favor, identifícate"
redirect_to :controller => 'user', :action => 'login'
end
end
flash, hay una variable de tipo Hash llamada session
que permite almacenar información de sesión
def login
user = User.find(:first,
:conditions => "name = '#{params[:name]}'
and password = '#{params[:password]}'")
if user
session[:user_id] = user.id
redirect_to :action => 'index'
else
reset_session
flash[:note] = 'Nombre de usuario o contraseña inválidos'
end
end
ActionView se encarga de renderizar las plantillas que devolverá Rails como respuesta al usuarioapp/views/controlador/ RXML: ficheros .rxml que producen como resultado XMLRHTML: ficheros .rhtml que producen como resultado (X)HTML<%= %>: la ejecución de la plantilla produce un contenido<% %>: no se genera ningún código
app/views/clients/view.rhtml
... <% @clients.each do |client| %> <td><%= client.name %></td> <% end %> ...
<% %> y <%= %>, ActionView
define una serie de ayudas para generar código mucho más compacto.
<%= human_size 34567 %> » 35 kb <%= time_ago_in_words Time.local(2004,10,13) %> » 470 days <%= number_with_precision 65.0/3, 3 %> » 21.667 <%= truncate program.name, 20 %> » La cocina de Arg...
<%= link_to 'Eliminar', :action => 'delete' %> <%= link_to 'Eliminar', {:action => 'delete', :controller => 'clients'}, {:class => 'enlace-home', :confirm => '¿Estás seguro?'} %> <%= image_tag "images/home.png", :class => "img-small", :size => "320x240" %> <%= image_tag "home", :class => "img-small", :size => "320x240" %> <%= mail_to "soporte@tecnicos.com", "Servicio Técnico", :subject => 'Avería' %>
ActionView y ActiveRecord definen un objeto Pagination: a nivel de vista muestra los enlaces necesarios, mientras que a nivel de objeto se encarga de recuperarlos de la base de datos
def list @client_pages, @clients = paginate :clients, :per_page => 10 end
<%= pagination_links @client_pages %>
<%= start_form_tag :action => 'create' %> <p><label for="client_nif">Nif</label><br/> <%= text_field 'client', 'nif' %></p> <p><label for="client_razon_social">Razón social</label><br/> <%= text_field 'client', 'razon_social' %></p> <%= submit_tag "Create" %> <%= end_form_tag %>
<form action="/clients/create" method="post"> <p><label for="client_nif">Nif</label><br/> <input id="client_nif" name="client[nif]" size="30" type="text" value="" /></p> <p><label for="client_razon_social">Razón social</label><br/> <input id="client_razon_social" name="client[razon_social]" size="30" type="text" value="" /></p> <input name="commit" type="submit" value="Create" /> </form>
params = { 'client' => {:nif => '12345323N',
:razon_social => 'Pinturas Esponja' },
'action' => 'create'}
text_field :variable, :attribute, options hidden_field :variable, :attribute, options password_field :variable, :attribute, options text_area :variable, :attribute, options check_box :variable, :attribute, options, on_value, off_value select :variable, :attribute, choices, options html_options
<p><label for="proposal_estado">Estado</label><br/> <%= select :proposal, :estado, %w{Aceptada Recibida Preparación} %></p>
app/views/layouts application.rhtml <%= content_for_layout %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="es"> <head> <title>Maitre</title> </head> <body> <div class="message"> <%= flash['note'] %> </div> <%= @content_for_layout %> </body>
now = Time.now puts now » Sun Jan 29 11:02:54 CET 2006 puts 20.minutes.ago » Sun Jan 29 10:43:29 CET 2006 puts 3.days.ago » Thu Jan 26 11:03:45 CET 2006 puts now.at_midnight » Sun Jan 29 00:00:00 CET 2006 puts now.next_week » Mon Jan 30 00:00:00 CET 2006 puts now.tomorrow » Mon Jan 30 11:02:54 CET 2006 puts now.tomorrow.tomorrow » Tue Jan 31 11:02:54 CET 2006