Ver contenidos de mis usuarios favoritos

Las tablas son usuarios(id, nick, …), favoritismos(usuario_id,
favorito_id, …) y contenidos(titulo, usuario_id, created_at, …)

Definición de usuario (en el modelo):
has_many :favoritos, :through => :favoritismos, :class_name =>
‘Usuario’, :order => “nick”
has_many :contenidos, :order => “created_at desc”

Es decir, un usuario (yo) tiene contenidos y tiene usuarios favoritos.
El lío es para acceder a los contenidos de los usuarios favoritos desde
el controlador:

La forma lógica sería:
@contenidos = @usuario.favoritos.contenidos
Pero eso no funciona: “undefined method `contenidos’ for Usuario:Class”
A pesar de que sí funcionan
@usuario.favoritos
y
@usuario.contenidos
Igual el problema está en que falta en el modelo de usuarios el
“belongs_to favoritos” correspondiente, pero no sé cómo ponerlo…

Un segundo intento sería:
@contenidos = Contenido.find(:all, :order => ‘c.created_at desc’,
:conditions => “f.usuario_id = #{@usuario.id}”, :joins => “as c inner
join favoritismos as f on f.favorito_id = c.usuario_id” )

Y eso sí que devuelve los contenidos… pero si en la vista intentas
mostrar el autor del contenido:
contenido.usuario.nick
En vez de salir el nick del autor (mi usuario favorito), sale el nick
mío. Deduzco que como tanto la tabla contenidos como la tabla
favoritismos tienen un campo usuario_id, ruby se monta un lío…

Y así estoy, sin saber cómo sacar esto. A ver si alguien me echa una
mano…

Fernando:

Creo que te estas haciendo un lio con el has_many auto-referencial. Como
primer paso, fijate que tu “has_many :contenidos” funcione
apropiadamente para un usuario “comun”. Es decir

User.find(:first).contenidos => Deberia arrojar un array de contenidos,
aunque sea vacio.

Ahora pensa esto: “has_many :favoritos, …” te va a devolver un array
de Users. Cada user tendra sus contenidos, de manera que tu lista de
contenidos sera la suma de los contenidos de cada usuario favorito:

user= User.find(:first)
lista_usuarios= user.favoritos(:include => “contenidos”) # (no estoy
seguro de que el include funcione aqui).

contenidos_de_favoritos= []

lista_usuarios.each do |user|
contenidos_de_favoritos << user.contenidos
end

Si queres, podes agregar eso como un metodo de User:

class User < ActiveRecord::Base

def contenidos_de_favoritos
returning([]) do |contenidos|
self.favoritos.each do |fav_user|
contenidos << fav_user.contenidos
end
end
end

end

Quizas halla una forma mas facil o directa, podes probar con has_many
:through, pero no se si sera posible.

Fernando C. wrote:

Las tablas son usuarios(id, nick, …), favoritismos(usuario_id,
favorito_id, …) y contenidos(titulo, usuario_id, created_at, …)

Definición de usuario (en el modelo):
has_many :favoritos, :through => :favoritismos, :class_name =>
‘Usuario’, :order => “nick”
has_many :contenidos, :order => “created_at desc”

Es decir, un usuario (yo) tiene contenidos y tiene usuarios favoritos.
El lío es para acceder a los contenidos de los usuarios favoritos desde
el controlador:

La forma lógica sería:
@contenidos = @usuario.favoritos.contenidos
Pero eso no funciona: “undefined method `contenidos’ for Usuario:Class”
A pesar de que sí funcionan
@usuario.favoritos
y
@usuario.contenidos
Igual el problema está en que falta en el modelo de usuarios el
“belongs_to favoritos” correspondiente, pero no sé cómo ponerlo…

Un segundo intento sería:
@contenidos = Contenido.find(:all, :order => ‘c.created_at desc’,
:conditions => “f.usuario_id = #{@usuario.id}”, :joins => “as c inner
join favoritismos as f on f.favorito_id = c.usuario_id” )

Y eso sí que devuelve los contenidos… pero si en la vista intentas
mostrar el autor del contenido:
contenido.usuario.nick
En vez de salir el nick del autor (mi usuario favorito), sale el nick
mío. Deduzco que como tanto la tabla contenidos como la tabla
favoritismos tienen un campo usuario_id, ruby se monta un lío…

Y así estoy, sin saber cómo sacar esto. A ver si alguien me echa una
mano…

Al final, este “robatiempos” tenía una solución muy sencilla: Tirar del
viejo y eficaz SQL:

  @contenidos = Contenido.find_by_sql("

select contenidos.*
from contenidos, favoritismos
where favoritismos.usuario_id = #{@usuario.id}
and favoritismos.favorito_id = contenidos.usuario_id")

Cuando se montan líos de relaciones “complicadas”, si hay problemas,
esta experiencia me dice que es mejor resolverlo “a mano”, y dejar el
tema de los modelos y clases para los casos más normales. Ninguna
solución va a resolver este problema de forma más eficaz ni sencilla…
ninguna que yo sepa, y he oído unas cuantas (como la de Emmanuel O., te
agradezco tu ayuda en todo caso!!)

s2