Realaciones: has_many :through del mismo modelo

Hola a todos,

Llevo unos dias peleandome con unas relaciones un tanto atipicas y no
doy con la solución.

Necesito representar una especie de arbol donde un nodo puede tener
varios hijos y varios padres, por lo que acts_as_tree no me vale. Lo
estoy haciendo mediante has_many :through porque ademas cada relación
debe guardar algunos datos mas.

Los modelos que estoy usando son:
class Category < ActiveRecord::Base
has_many :parents, :class_name => ‘Relationship’
has_many :children, :class_name => ‘Relationship’, :foreign_key =>
‘parent_id’
has_many :categories, :through => :relationships
end

class Relationship < ActiveRecord::Base
belongs_to :category
belongs_to :category, :foreign_key => “parent_id”
end

y las migraciones contienen:

class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :name
t.timestamps
end
Category.create :name => “A”
Category.create :name => “B”
Category.create :name => “C”
Category.create :name => “D”
Category.create :name => “E”
end
def self.down
drop_table :categories
end
end

class CreateRelationships < ActiveRecord::Migration
def self.up
create_table :relationships do |t|
t.integer :category_id
t.integer :parent_id

  t.timestamps
end
Relationship.create :category_id => 2, :parent_id => 1
Relationship.create :category_id => 3, :parent_id => 1
Relationship.create :category_id => 2, :parent_id => 3
Relationship.create :category_id => 5, :parent_id => 1
Relationship.create :category_id => 4, :parent_id => 5
Relationship.create :category_id => 2, :parent_id => 5

end
def self.down
drop_table :relationships
end
end

Entonces cuando desde una consola hago, por ejemplo:
Category.find(:first).children

Me muestra objetos de la clase Relationship en los que la categoria con
id 1 esta como parent_id, cuando creo que deberia de mostrar objetos de
la clase Category que son los hijos, en otras palabras me muestra
registros de la tabla relationships en lugar de registros de la tabla
categories.

1- ¿A que se debe esto?, seguro que me he equivocado en algo al definir
las relaciones en los modelos pero al utilizar dos veces el mismo modelo
estoy perdiendo la cabeza.

2- ¿Como deberia de definir un metodo para que cuando pregunte por
padres no solo me muestre los padres/hijos directos, sino también toda
la rama hacia arriba/abajo?

3- ¿Existe algún plugin como acts_as_tree que me permita hacer esto y me
estoy volviendo loco por gusto?

Saludos y gracias!

El día 23 de enero de 2009 14:52, Ancor C.
[email protected]
escribió:> Los modelos que estoy usando son:

class Category < ActiveRecord::Base
has_many :parents, :class_name => ‘Relationship’
has_many :children, :class_name => ‘Relationship’, :foreign_key =>
‘parent_id’
has_many :categories, :through => :relationships
end

No entiendo como esto te funciona… el parámetro :through debe hacer
referencia a alguno de los nombres de los has_many que tienes en el
modelo, en este caso: parents o children.

Puedo estar equivocado, sólo te comento como yo lo uso.

class Relationship < ActiveRecord::Base
belongs_to :category
belongs_to :category, :foreign_key => “parent_id”
end

Esto sí que es raro porque estás declarando la relación 2 veces…

No sigo porque con esto ya sólo no me estraña que tengas
comportamientos extraños.

:confused:

f.

2009/1/23 Ancor C. [email protected]:

Necesito representar una especie de arbol donde un nodo puede tener
varios hijos y varios padres, por lo que acts_as_tree no me vale. Lo
estoy haciendo mediante has_many :through porque ademas cada relación
debe guardar algunos datos mas.

Yo creo que lo que quieres hacer es esto …

"self-referential many-to-many relationship"

Hay varios sitios web que explican como se hace. Tambien aparece en el
libro Rails Recipes, receta número 18.

Muchisimas gracias, es exactamente lo que estaba buscando. Le he dado un
vistazo al libro Rails Recipes y parece estar muy bien, lo compraré.

Lo “sencillo” que es y todo el tiempo que he perdido.

Gracias a ti también Fernando G…

Saludos.

Francesc E. wrote:

2009/1/23 Ancor C. [email protected]:

Necesito representar una especie de arbol donde un nodo puede tener
varios hijos y varios padres, por lo que acts_as_tree no me vale. Lo
estoy haciendo mediante has_many :through porque ademas cada relación
debe guardar algunos datos mas.

Yo creo que lo que quieres hacer es esto …

"self-referential many-to-many relationship"

Hay varios sitios web que explican como se hace. También aparece en el
libro Rails Recipes, receta número 18.

Creo que me he precipitado, no es “exactamente” lo que necesito, porque
luego debe entrar en la relación otro modelo más y creo que habtm no
permite este tipo de relaciones, pero ya sabiendo como se llama lo que
estoy buscando seguro que no tardo en dar con la solución.

Gracias!

Ancor C. wrote:

Muchisimas gracias, es exactamente lo que estaba buscando. Le he dado un
vistazo al libro Rails Recipes y parece estar muy bien, lo compraré.

Lo “sencillo” que es y todo el tiempo que he perdido.

Gracias a ti también Fernando G…

Saludos.

Francesc E. wrote:

2009/1/23 Ancor C. [email protected]:

Necesito representar una especie de arbol donde un nodo puede tener
varios hijos y varios padres, por lo que acts_as_tree no me vale. Lo
estoy haciendo mediante has_many :through porque ademas cada relación
debe guardar algunos datos mas.

Yo creo que lo que quieres hacer es esto …

"self-referential many-to-many relationship"

Hay varios sitios web que explican como se hace. También aparece en el
libro Rails Recipes, receta número 18.

Hola de nuevo,

me he vuelto a quedar bloqueado con este tema de las relaciones:

ahora mismo tengo estas relaciones

class Category < ActiveRecord::Base

Relationships

has_many :site_configurations, :foreign_key => “root_category_id”

has_many :category_as_children, :foreign_key => ‘child_id’,
:class_name => ‘MenuNode’, :dependent => :destroy
has_many :category_as_parents, :foreign_key => ‘category_id’,
:class_name => ‘MenuNode’, :dependent => :destroy
has_many :parents, :through => :category_as_children, :order => ‘name’
has_many :children, :through => :category_as_parents, :order =>
‘name’
end

class SiteConfiguration < ActiveRecord::Base
belongs_to :root_category, :class_name => ‘Category’
has_many :relation_in_sites, :foreign_key => ‘site_id’, :class_name =>
‘MenuNode’, :dependent => :destroy
end

class MenuNode < ActiveRecord::Base
belongs_to :child, :class_name => ‘Category’
belongs_to :parent, :class_name => ‘Category’, :foreign_key =>
‘category_id’
belongs_to :site, :class_name => ‘SiteConfiguration’
end

Con estas relaciones puedo, entre otras cosas, ver que categorias hijas
(subcategorias) contiene una categoria y ademas, ver que categorias
padre (supercategorias) tiene una categoria, además puedo ver las
relaciones (MenuNode) en las que una categoria es padre o hija, hasta
ahi bien, pero al entrar en juego otro modelo más, en este caso,
SiteConfiguration no consigo sacarle el partido que me gustaria, creo
que me falta alguna relacion mas.

Mi objetivo de todo esto es poder sacar las categorias hijas
(subcategorias) de una categoria pero de una determinada configuracion
de sitio (SiteConfiguration).

La verdad que no se si esto lo puedo hacer añadiendo alguna relación más
o tengo que hacerlo mediante un metodo en la clase Category.

PD: Por si no queda muy claro lo que quiero conseguir, se trata de
realizar diferentes menus (ordenaciones) de categorias jerarquicas,
donde una categoria puede tener tantos padres e hijos (supercategorias y
subcategorias) como se desee, evitando ciclos. Y poder recorrer estos
menus (ordenaciones) sin que interfieran los unos con los otros.

Gracias,

Finalmente he dado con la solución. Por si a alguien le sirve estos
links lo explican muy bien:

http://railsforum.com/viewtopic.php?id=1707
http://blog.hasmanythrough.com/2007/10/30/self-referential-has-many-through

Saludos.

Ancor C. wrote:

Creo que me he precipitado, no es “exactamente” lo que necesito, porque
luego debe entrar en la relación otro modelo más y creo que habtm no
permite este tipo de relaciones, pero ya sabiendo como se llama lo que
estoy buscando seguro que no tardo en dar con la solución.

Gracias!

Ancor C. wrote:

Muchisimas gracias, es exactamente lo que estaba buscando. Le he dado un
vistazo al libro Rails Recipes y parece estar muy bien, lo compraré.

Lo “sencillo” que es y todo el tiempo que he perdido.

Gracias a ti también Fernando G…

Saludos.

Francesc E. wrote:

2009/1/23 Ancor C. [email protected]:

Necesito representar una especie de arbol donde un nodo puede tener
varios hijos y varios padres, por lo que acts_as_tree no me vale. Lo
estoy haciendo mediante has_many :through porque ademas cada relación
debe guardar algunos datos mas.

Yo creo que lo que quieres hacer es esto …

"self-referential many-to-many relationship"

Hay varios sitios web que explican como se hace. También aparece en el
libro Rails Recipes, receta número 18.