Old Emmanuel Oga's Weblog (new one is at www.emmanueloga.com)

Tablas en rails

Posted in Uncategorized by emmanueloga on septiembre 20, 2007

Bueno, parece que hace falta mas informacion para rails en español. Ya que escribi un email semi-largo hacerca de como utilizar relaciones sencillas entre tablas, y parece que a alguien le resulto util, lo posteo aca.

“…A ver…, si tenes dos tablas, users y documents, y la relacion es que cada usuario tiene muchos documentos, entonces tus tablas podrian ser algo como:

users:
id: integer
name: string

documents
id: integer
name: string
content: text
user_id: integer << Clave foranea

Si queres, podes crear esas tablas mediante migraciones… (mmm, si, es otro tema, aunque rails lo hace sencillo tambien)

Estas tablas tienen en cuenta las convenciones de rails, donde el nombre de la clave foranea debe ser el singular del nombre de la tabla a la que apunta dicha clave, agregandole el postfijo _id (la clave user_id apuntara a la tabla users). Todo esto se puede configurar “a mano” en las relaciones, pero si tenes la posibilidad, es recomendable seguir las convenciones.

En tus clases active record agregas las relaciones entre tablas. Por ejemplo:

class User < ActiveRecord::Base
has_many :documents
end

class Document
belongs_to :user
end

Fijate que, si sabes algo de ingles, las definiciones son bastante naturales. El Ususario tiene muchos documentos, y el Documento pertenece a un Usuario.

Ahora podes acceder a los documentos del usuario asi:

usuario= User.create :name => “Lolo”
usuario.documents => [] #Vacio, no tiene nada
usuario.documents.create :name => “La historia de mi vida” # creo un documento

o

doc= Document.create :name => “La historia de mi vida” # doc.user => null
doc.user= User.find :first # Le asigno el primer usuario que encuentro
doc.save

Si queres hacer cosas “mas complicadas”, podes agregar un metodo a tu clase. Por ejemplo:

class User < ActiveRecord::Base
has_many :documents

def create_two_documents nombre1, nombre2
User.transaction do
self.documents.create :name => nombre1
self.documents.create :name => nombre2
end
end
end

user= User.find_or_create_by_name “Lolo”
user.create_two_documents “Mi Biografia”, “Himnos a mi mismo”

Aqui lolo crea dos registros en la tabla documents que apuntan a si mismo. Del mismo modo podes acceder a cualquier tabla que quieras actualizar…”

3 comentarios

Subscribe to comments with RSS.

  1. head777 said, on marzo 26, 2010 at 7:29 pm

    Hola, que tal acabo de leer tu manual y me parece muy entendible ya que estoy empezando en el mundo de rails.

    Pero me gustaria preguntarte un par de cosas, ya que no entiendo muy bien como manejar tablas intermedias.

    Ejemplo: imagina que tienes una base de datos ya montada y funcionando y en ella tienes estas tres tablas:

    pedido
    producto
    y una intermedia detalle_pedido en la que esta pedido_id, producto_id para hacer la ruptura de este tipo de relaciones

    Entonces en este caso, como la manejas es decir a la hora de crear los modelos creas el modelo asi:

    script/generate model detalle_pedido ???

    Tengo problemas para manejar este tipo de tablas, ya que no se si es correcto crear modelos y controles con nombres asi: ” detalle_pedido” me refiero por que son dos nombres y aparte lleva el guion o quiza seria mejor crear los dos en esta manera “detalle” y de igual forma el modelo aunque despues dentro de el le especifique que tipo tabla usara con el set_name_table ??

    Que opinas ando un poco perdido nada mas con este tipo de tablas, ya que no se haya en internet ningun tipo de esta y soy algo nuevo.

    Bueno espero me puedas ayudar, desde ya gracias!!

    • emmanueloga said, on marzo 26, 2010 at 10:06 pm

      Te paso algunos links, este lista esta buena para hacer preguntas en español:
      http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar

      Las guías de rails, están en ingles pero son barbaras:
      http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

      La documentación de rails, lo que estas necesitando es una relación “many to many”.
      Esto se logra sin join model mediante el método “has_and_belongs_to_many” o con join model mediante el método “has_many :trough” .
      http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001833

      Join model quiere decir que vas a tener una clase para representar la tabla que relaciona ambos modelos, en tu caso sería DetallePedido.
      Te recomiendo que trates de poner todo en inglés, es más claro si tu código esta en un solo idioma.


      class Order
      set_table_name "pedido"
      has_many :order_details
      has_many :products, :through => :order_details
      end
      class Product
      set_table_name "producto"
      has_many :order_details
      has_many :orders, :through => :order_details
      end
      class OrderDetail < ActiveRecord::Base
      belongs_to :order
      belongs_to :product
      end

      # Ahora tendrías que poder hacer cosas como:
      Order.first.products
      Product.first.orders
      OrderDetail.all.each do |od|
      puts "#{ od.order } has #{ od.products.count } products"
      end
      # etc....

      Como tu tabla parece legacy, seguro vas a tener que configurar los nombres de las claves en los belongs_tos y has_manys.
      Investiga bien la documentación de opciones como :foreign_key, :association_foreign_key.

      Cualquier duda no dudes en preguntar en la lista que te pasé más arriba!

      Saludos.

  2. head777 said, on marzo 27, 2010 at 12:52 am

    Hola, te estoy muy agradecido por que ya aprendi que en casos como estos es mejor hacer un “has_and_belongs_to_many” o tambien se puede hacer por medio del “through” por que por medio de esto generamos una asociasion rapida y sin tanto problema.

    Solo que ahora nada mas una consulta, que no me contestaste la vez pasada xD, ahora que ya se como relacionar tablas many a many. Lo que necesito saber es como llamar los modelos y los controles cuando los cree en la consola, ya que he no se si es lo mas recomendado crear modelos y controles asi: “detalle_pedido” por que primero son dos nombres y segundo lleva guion.

    Que opinas??


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: