Hola, estoy tratando de definir correctamente (o sea, elegantemente)
un modelo (o modelos) para los datos de dos tablas cuya estructura,
aunque simple, no es muy agracedida.
Las tablas son “usuarios” y “grupos”:
usuarios
- id
- username
- domain
- more_data
(username + domain es UNIQUE)
grupos
Como veis no hay relación entre tablas, y encima cada entrada en la
tabla “groups” NO es un grupo único, si no un grupo perteneciente a
dicho username@domain. Es decir, para decir que un usuario
“[email protected]” pertenece a los grupos GRUPO_A y GRUPO_B habrÃa que
crear 2 entradas en la tabla “groups”:
id username domain group
1 pepe dominio.com GRUPO_A
2 pepe dominio.com GRUPO_B
Intento entonces crear un atributo “grupos” en el modelo de “Usuario”
que me devuelva un Array con los nombres de los grupos a los que
pertenece. Para ello he creado un modelo “Grupo” que accede a su tabla
“grupos”.
Hasta ahora sólo se me ocurre definir esto en el modelo “Usuario”:
def grupos()
grupos = Grupo.find(:all, :conditions => { :username =>
self.username, :domain => self.domain })
grupos.“posible marranada para extraer sólo los nombres de grupo a un
array”
end
Lo que pasa es que eso no me devuelve un Array con nombres de grupo,
sino un Array con objetos de tipo “Grupo” y tendrÃa que hacer alguna
“marranada” para desde ahà crear el array que busco.
Dudas:
- ¿Debo hacer esa “marranada”?
- ¿Hay alguna otra forma de definir el modelo o la relación entre
modelos para conseguir esto más elegantemente? (obviamente no me sirve
“has_many :grupos” ya que ni existe clave foránea y encima es una
clave compuesta “username+domain”).
Gracias por cualquier sugerencia. Saludos.
El 20/02/08, Iñaki Baz C. [email protected] escribió:
Lo que pasa es que eso no me devuelve un Array con nombres de grupo,
sino un Array con objetos de tipo “Grupo” y tendrÃa que hacer alguna
“marranada” para desde ahà crear el array que busco.
Dudas:
- ¿Debo hacer esa “marranada”?
Finalmente he hecho dicha “marranada” que ha resultado no serlo tanto:
def grupos()
grp_entries = Grupo.find(:all, :conditions => { :username =>
self.username, :domain => self.domain })
grupos = Array.new
grp_entries.each {|grp_entry| grupos.push(grp_entry.name)}
grupos
end
¿Se os ocurre algo más elegante o tiro con esto? ![:slight_smile: :slight_smile:](https://www.ruby-forum.com/images/emoji/apple/slight_smile.png?v=12)
Hola,
sin saber mucho me parece que esto es un clasico :has_many
Usuario
:has_many :grupos
:Aqui_va_la_restricción_de_unicidad_para_los_campos username+domain
Grupo
:belongs_to :usuario
y las tablas te quedarÃan asi
Usuario (id, username, domain, other_data)
Grupo (id, usuario_id, grupo)
puedes prescindir en la tabla Grupo de los campos username y domain, ya
que al poner la restricción en la tabla Usuario de unicidad a
username+domain solo te basta con el id de Usuario para identificarlo
“unequivocamente” (si es que existe esa palabra :D).
Con esto puedes usar los clásicos find para acceder a los grupos de un
usuario.
Me corrigen si me equivoco.
Saludos
Sergio
La Serena
Chile.
Iñaki Baz C. escribió:
On 20/02/2008, Iñaki Baz C. [email protected] wrote:
¿Se os ocurre algo más elegante o tiro con esto? ![:slight_smile: :slight_smile:](https://www.ruby-forum.com/images/emoji/apple/slight_smile.png?v=12)
Esto que has hecho se puede solucionar así
grupos = Grupo.find(:all, :conditions => { :username =>self.username,
:domain => self.domain }, :select => ‘grupo’)
nombres_grupos = grupos.collect(&:grupo)
Pero no entiendo si el modelo de datos lo has hecho tú o es legacy y
tienes que tirar con él. Si puedes cambiarlo, lo normal es que tengas
una tabla User con los datos de usuario, una Grupos con los datos del
grupo y, o bien una tabla de cruce y un relación habtm o, para mi
mejor, un modelo Pertenencia que te sirva para relacionar Grupos y
Ususarios mediante un has_many :through
–
Manuel, que
piensa que eres una excelente persona y medra en torno a
http://simplelogica.net y/o http://simplelogica.net/logicola/
Recuerda comer mucha fruta y verdura.
Hola,
¿Porque no puedes hacer has_many: grupos? ¿No puedes modificar las
tablas?
Me parece que es una relación muchos a muchos (ya que un usuario puede
estar
en varios grupos) y necesitas una tabla intermedia “grupos_usuarios”,
con
este nombre, para que Rails la reconozca sin problemas (nombres en orden
alfabético)
class Usuario
has_and_belongs_to_many :grupos
class Grupo
has_and_belongs_to_many :usuarios
y la tabla intermedia
grupos_usuarios (
grupo_id
usuario_id
)
y naturalmente eliminas de la tabla grupos los atributos username y
domain.
Puedes mantener el unique de usuarios, si es que un usuairo pertenece a
un
sólo dominio, si no es asà harÃa una tabla Dominios.
Creo que mejor modificas las tablas, más que “parchar”, si no, más
adelante
tendras más problemas.
–
Saludos
Atte.
Jean Marcel Droguett.
El dÃa 20/02/08, Iñaki Baz C. [email protected] escribió:
El 20/02/08, Manuel González Noriega
[email protected] escribió:
grupos
nombres_grupos = grupos.collect(&:grupo)
Qué buena !! No habÃa visto el parámetro “select” ![:wink: :wink:](https://www.ruby-forum.com/images/emoji/apple/wink.png?v=12)
Pero no entiendo si el modelo de datos lo has hecho tú o es legacy y
tienes que tirar con él. Si puedes cambiarlo, lo normal es que tengas
una tabla User con los datos de usuario, una Grupos con los datos del
grupo y, o bien una tabla de cruce y un relación habtm o, para mi
mejor, un modelo Pertenencia que te sirva para relacionar Grupos y
Ususarios mediante un has_many :through
Lo sé, pero las tablas vienen asà de fábrica y no se pueden cambiar ![:frowning: :frowning:](https://www.ruby-forum.com/images/emoji/apple/frowning.png?v=12)
Muchas gracias.
El 20/02/08, Jean D. [email protected] escribió:
Hola,
¿Porque no puedes hacer has_many: grupos? ¿No puedes modificar las tablas?
Gracias, pero no puedo modificar las tablas en absoluto, las usa otra
aplicación y deben ser asÃ.
No obstante ya lo he dejado bastante bonito con la sugerencia de
Manuel Gonzalez.
Saludos.