Relaciones en Rails 3(1 1,1 n,n n)
-
Upload
david-guevara -
Category
Documents
-
view
348 -
download
0
description
Transcript of Relaciones en Rails 3(1 1,1 n,n n)
Desarrollo web con Ruby on Rails 3ActiveRecord: asociaciones entre clases
Áncor González Sosa Imobach González Sosa
Banot.nethttp://www.banot.net/
Octubre de 2010
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 1 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 2 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 3 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 4 / 64
Los objetos no "viven" aislados
ActiveRecord ofrece mecanismos para relacionar modelosAPI potente, flexible y fácil de usarLas relaciones se declaran estilo "macro"Siguiendo las convenciones, se reduce al mínimo el código
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 5 / 64
¿Puede ser más simple?
class Artist < ActiveRecord::Basehas_many :albums
end
class Album < ActiveRecord::Basebelongs_to :artist
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 6 / 64
¿Puede ser más simple?
album = Album.new(:title => "Born under a bad sign")albert = Artist.find_by_name("Albert King")album.artist = albertalbert.albums.each { |a| puts a.title }
gary = Artist.find_by_name("Gary Moore")gary.albums << Album.new(:title => "King of the blues")gary.albums.build(:title => "Wild frontier")
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 7 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 8 / 64
Especificación
class Company < ActiveRecord::Basehas_one :office
end
class Office < ActiveRecord::Basebelongs_to :company
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 9 / 64
Tablas
companiesidname string
officesidnumber stringarea integercompany_id integer
11
has_one
belongs_to
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 10 / 64
Referencias en las migraciones
Se puede usar el método references en la definición de tablas
create_table :offices do |t|t.string :numbert.decimal :areat.references :customer # customer_idt.timestamps
end
De todos modos, no deja de ser un entero:
create_table :offices do |t|t.string :numbert.decimal :areat.integer :customer_idt.timestamps
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 11 / 64
Métodos de belongs_to
association(force_reload = false)
office.company
association=(associate)
office.company = Company.first
build_association(attributes = {})
office.build_company(:name => "Banot.net")
create_association(attributes = {})
office.create_company(:name => "Inventiaplus")
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 12 / 64
Métodos de has_one
association(force_reload = false)
office.company
association=(associate)
office.company = Company.first
build_association(attributes = {})
office.build_company(:name => "Banot.net")
create_association(attributes = {})
office.create_company(:name => "Inventiaplus")
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 13 / 64
¿Cuándo se guardan los objetos?has_one
El objeto asociado se guarda al asignarlo para actualizar su claveajenaEl objeto reemplazado (si lo hubiera), también se guardaExcepto:
I Si falla una de las validaciones, se cancela la asignaciónI Si el extremo que tiene el has_one es nuevo, se esperará (a que
este se guarde)
Para asignar sin guardar, usar el método build
Si se asigna por el extremo que tiene el belongs_to, nunca seguardan los objetos
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 14 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 15 / 64
Especificación
class Artist < ActiveRecord::Basehas_many :albums
end
class Album < ActiveRecord::Basebelongs_to :artist
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 16 / 64
Tablas
artistsidname string
albumsidtitle stringartist_id integer
1n
has_many belongs_to
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 17 / 64
Métodos de has_many (I)
collection(force_reload = false)
artist.albums
collection<<(associate)
artist.albums << Album.new
delete(object)
artist.delete(album)
collection=(objects)
albums.class # Arrayoffice.albums = albums
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 18 / 64
Métodos de has_many (II)
collection_singular_ids / collection_singular_ids=
artist.album_ids # [1, 2]artist.album_ids = [1, 3]
clear
artist.albums.clearartist.albums # []
empty?
artist.albums.empty?
size
artist.albums.size
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 19 / 64
Métodos de has_many (III)
find(...)
artist.albums.find_by_year(2010)artist.albums.find(:conditions => { ... })
clear
artist.albums.clearartist.albums # []
exists?
artist.albums.exists?(:year => 2010)
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 20 / 64
Métodos de has_many (y IV)
collection.build(attributes = {})
a = artist.albums.build(:title => "Believe")a.new_record? # truea.save!
collection.create(attributes = {})
a = artist.albums.create(:title => "Asylum")a.new_record? # false
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 21 / 64
¿Cuándo se guardan los objetos?has_many
Los objetos asociados se guardan al asignarlosExcepto:
I Si falla la validación de cualquiera de ellos, la asignación secancela
I Si el extremo que tiene en has_many es nuevo, se esperará (hastaque se guarde)
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 22 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 23 / 64
Especificación
class Musician < ActiveRecord::Basehas_and_belongs_to_many :bands
end
class Band < ActiveRecord::Basehas_and_belongs_to_many :musicians
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 24 / 64
Tablas
bandsidname string
has_and_belongs_to_many
musiciansidname string
has_and_belongs_to_many
bands_musiciansband_id integermusician_id integer
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 25 / 64
La tabla intermedia
El nombre se forma contatenando los plurales de los nombres delas clasesSe ordenan alfabéticamenteHay que indicar que no precisa clave primaria
create_table :companies_offices, :id => false do |t|t.references :companyt.references :office
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 26 / 64
Parecidos con has_many
Simplificando, la API es la misma que en el caso de has_many
Las reglas para guardar los objetos en la base de datos tambiénson las mismasAsí que vamos a aplicar el principio DRY ;)
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 27 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 28 / 64
Usando la API de consultas
artist = Artist.find_by_name(’B.B. King’)artist.albums.where("year < 2000")
Simplificando, se traduce en:
SELECT * FROM "artists" LEFT OUTER JOIN "albums"ON "albums"."artist_id" = "artists"."id"WHERE (albums.year < 2000)
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 29 / 64
Eager-loadingn + 1 consultas
albums = Album.limit(10)albums.each do |album|puts "#{album.artist.name}: #{album.title}"
end
Esto dispararía 1 consulta para recuperar los álbums. . .. . . y otra por cada album para recuperar su artista¡En total, 101 consultas!
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 30 / 64
Eager-loadingDe n + 1 a tan sólo 2
albums = Album.includes(:artist).limit(10)
Esto dispara sólo 2 consultas:I Una para los álbumsI Y otra para todos los artistas relacionados
SELECT albums.* FROM albums LIMIT 10SELECT artists.* FROM artists WHEREWHERE (albums.artist_id IN (1, 2, 5))
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 31 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 32 / 64
Dependencias entre objetos
A veces la existencia de un objeto depende de otroSi por ejemplo borramos un artista, nos interesa borrar sus discos
class Artisthas_many :albums, :dependent => :destroy
end
u2 = Artist.find_by_name(’U2’)u2.destroy # Elimina a U2 y todos sus álbums
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 33 / 64
Tipos de dependencia
destroy Llama a destroy para cada uno de los objetosasociados
delete/delete_all Borra los objetos asociados pero sin llamar adestroy
nullify Pone la clave ajena a nullrestrict No permite borrar el objeto si hay otro asociado
Se usan principalmente con has_many y has_oneDebe evitarse su uso en belongs_to por la posibilidad de dejarobjetos "huérfanos"
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 34 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 35 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 36 / 64
No siempre es posible
Seguir las convenciones permite escribir menos código. . .pero no siempre es posibleAfortunadamente, ActiveRecord ofrece un buen número demodificadores
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 37 / 64
Ignorando las convenciones
class Log < ActiveRecord::Basehas_many :log_entries
end
class LogEntry < ActiveRecord::Basebelongs_to :log
end
log.log_entries # No parece muy bonito
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 38 / 64
Ignorando las convenciones
class Log < ActiveRecord::Basehas_many :entries, :class_name => "LogEntry"
end
class LogEntry < ActiveRecord::Basebelongs_to :log
end
log.entries # Mejor :)
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 39 / 64
Ignorando las convenciones
class Log < ActiveRecord::Basehas_many :entries, :class_name => "LogEntry",:foreign_key => "l_id"
end
class LogEntry < ActiveRecord::Basebelongs_to :log, :foreign_key => "l_id"
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 40 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 41 / 64
Ordenación
Permite ordenar los objetos dentro de la relación
class Artist < ActiveRecord::Basehas_many :albums, :order => :year
end
queen = Artist.find_by_name("Queen")queen.albums.map(&:year) # [ 1973, 1974, 1974, ... ]
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 42 / 64
Sentido de la ordenación
class Artist < ActiveRecord::Basehas_many :albums, :order => "year desc"
end
queen = Artist.find_by_name("Queen")queen.albums.map(&:year) # [ 1995, 1991, 1989, ... ]
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 43 / 64
Ordenación compuesta
class Artist < ActiveRecord::Basehas_many :albums, :order => "year asc, title desc"
end
queen = Artist.find_by_name("Queen")queen.albums.map(&:title)# [ "Queen", "Sheer heart attack", "Queen II", ... ]
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 44 / 64
Condiciones
Permite filtrar la relación con condiciones
class Artist < ActiveRecord::Basehas_many :albumshas_many :greatest_albums, :class_name => "Album",
:conditions => { :rate => [ 4, 5 ] }end
queen = Artist.find_by_name("Queen")queen.greatest_albums.first
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 45 / 64
Límites
Limita la cantidad de objetos devueltos
class Artist < ActiveRecord::Basehas_many :albums, :order => :yearhas_many :latest_albums, :class_name => "Album",
:limit => 2, :order => "year desc"end
queen = Artist.find_by_name("Queen")queen.latest_albums.map(&:year) # [ 1995, 1991 ]
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 46 / 64
EjercicioAñadiendo árbitros a Bet on Rails
1 Queremos que los usuarios de Bet on Rails sepan quién pita cadapartido
2 Añadir a Bet on Rails un modelo Referee que represente a losárbitros
3 Interesan su nombre y su fecha de nacimiento4 Implementar una gestión básica usando el "scaffold"5 Hacer que para cada partido se pueda seleccionar un árbitro
(pista: collection_select)6 ¿Cómo podría acceder a los partidos ya pitados por un árbitro?
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 47 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 48 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 49 / 64
Algo con dirección
class Address < ActiveRecord::Basebelongs_to :addressable, :polymorphic => true
end
class Company < ActiveRecord::Basehas_many :addresses, :as => :addressable
end
class Person < ActiveRecord::Basehas_one :address, :as => :addressable
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 50 / 64
¿Dónde está el truco?
Además de la columna _id, se usa una columna _type
En esa columna se guarda la clase del objeto asociado
address = Address.find_by_postal_code("35017")address.addressable_id # 1address.addressable_type # "Company"
En la migración hay que indicar que se trata de una relaciónpolimórfica
t.references :addressable, :polymorphic => true
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 51 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 52 / 64
¿Para qué?
Nos permite asociar dos modelos a través de un terceroUsos típicos:
1 Para añadir "lógica" a una asociación HABTM2 Como "atajo" en asociaciones has_many anidadas
Se verá más claro con dos ejemplos
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 53 / 64
Join models
Supongamos una asociación HABTM a la que queremos añadirlógica (atributos, validaciones, etc.)
class User < ActiveRecord::Basehas_and_belongs_to_many :groups
end
class Group < ActiveRecord::Basehas_and_belongs_to_many :users
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 54 / 64
Join models
Puede sustituirse por un modelo intermedio con dos relacionesuno a muchos
class User < ActiveRecord::Basehas_many :subscriptions
end
class Group < ActiveRecord::Basehas_many :subscriptions
end
class Subscription < ActiveRecord::Basebelongs_to :userbelongs_to :group
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 55 / 64
Join models
create_table :subscriptions do |t|t.references :usert.references :groupt.boolean :activet.timestamps
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 56 / 64
Join models
Así se puede llegar de un extremo al otro:
class User < ActiveRecord::Basehas_many :subscriptionshas_many :groups, :through => :subscriptions
end
class Group < ActiveRecord::Basehas_many :subscriptionshas_many :users, :through => :subscriptions
end
class Subscription < ActiveRecord::Basebelongs_to :userbelongs_to :group
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 57 / 64
Como si fuera HABTM
Se pueden usar los métodos habituales entre los extremosSe crearán "automáticamente" nuevos objetos intermediossiempre que sea necesarioCuando se eliminen, no se llamará a "destroy"
lanzarote = User.find_by_name("Lanzarote")lanzarote.groups.empty? # truelanzarote.subscriptions.empty? # trueknights = Group.find_by_name("Knights")lanzarote.groups << knightslanzarote.subscriptions.empty? # false
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 58 / 64
has_many anidados
class Document < ActiveRecord::Basehas_many :pages
end
class Page < ActiveRecord::Basebelongs_to :documenthas_many :paragraphs
end
class Paragraph < ActiveRecord::Basebelongs_to :page
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 59 / 64
has_many anidados
class Document < ActiveRecord::Basehas_many :pageshas_many :paragraphs, :through => :pages
end
class Page < ActiveRecord::Basebelongs_to :documenthas_many :paragraphs
end
class Paragraph < ActiveRecord::Basebelongs_to :page
end
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 60 / 64
Contenidos1 Asociaciones: lo básico
¿Qué son?Uno a unoUno a muchosMuchos a muchosAsociaciones y consultasDependencias
2 Asociaciones: opciones destacadasIgnorando las convencionesOrdenación y límites
3 Asociaciones avanzadasPolimórficashas_many :through
4 Herencia
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 61 / 64
Single Table Inheritance (STI)Todos los campos —de la clase base y las derivadas— en unatablaEl tipo concreto se almacena en la columna “type”Se puede pasar la opción --parent al generador
File
-path: string-size: integer
Text
-lines: string-words: integer
Binary
-format: string
filespath stringsize stringlines integerwords integerformat stringtype string
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 62 / 64
Ejercicio 1Modelando una plataforma de e-learning
Queremos escribir una plataforma de e-learningEn una primera versión, tenemos cursos, temas y tareas
I Cada curso tiene una serie de temas y tareas asociadasI Además, los temas y las tareas tienen asociados una serie de
documentos
Nuestros usuarios serán profesores y estudiantesUn curso puede tener varios profesores asignadosUn estudiante puede matricularse en cualquier curso
I Nos interesa saber cuándo formalizó la matrículaI Y también nos gustaría poder desactivarla en un momento dado
Implementarlo a nivel de modelos, olvidando la interfaz web
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 63 / 64
Ejercicio 2Modelando los equipos para Bet on Rails
1 Añadir a Bet on Rails un modelo Team que representa a losequipos e implementar una gestión básica (con el "scaffold")
2 La clase Game dejará de usar cadenas para representar a losequipos y usará esa nueva clase
3 Al crear/editar mediante el navegador deben seleccionarse losequipos de los registrados en la base de datos (pista:collection_select)
4 ¿Cómo podría acceder a los partidos que un equipo ha jugado encasa?
Áncor/Imobach GS (Banot.net) Desarrollo web con Ruby on Rails 3 Octubre de 2010 64 / 64