Doble unión con habtm en ActiveRecord
-
05-07-2019 - |
Pregunta
Tengo una situación extraña que implica la necesidad de una doble unión interna. He intentado la consulta que necesito, pero no sé cómo hacer que los rieles lo hagan.
Los datos
- Cuenta (has_many: sitios)
- Sitio (habtm: usuarios, pertenece a: cuenta)
- Usuario (habtm: sitios)
Ignora que son habtm o lo que sea, puedo hacerlos habtm o has_many: through.
Quiero poder hacer
@user.accounts
o
@account.users
Entonces, por supuesto, debería poder hacer
@user.accounts < @some_other_account
Y luego haga que @ user.sites incluya todos los sitios de @some_other_account.
He jugado con habtm y has_many: through pero no consigo que haga lo que quiero.
Básicamente necesito terminar con una consulta como esta (copiada de phpmyadmin. Probado y funciona):
SELECT accounts.*
FROM accounts
INNER JOIN sites ON sites.account_id = accounts.id
INNER JOIN user_sites ON sites.id = user_sites.site_id
WHERE user_sites.user_id = 2
¿Puedo hacer esto? ¿Es incluso una buena idea tener esta doble unión? Supongo que funcionaría mejor si los usuarios tuvieran la asociación con las cuentas para empezar, y luego se preocupe por obtener @ user.sites, pero funciona mejor para muchas otras cosas si se mantiene como está (usuarios < - > sitios).
Solución
Creo que es mejor crear métodos personalizados para esto en lugar de tratar de convertirlo en una asociación. Por ejemplo.
# in user.rb
def accounts
Account.all(:include => {:sites => :users}, :conditions => ["users.id=?", self])
end
def add_account(other_account)
other_account.sites.each do |site|
self.sites << site
end
end
# in account.rb
def users
User.all(:include => {:sites => :account}, :conditions => ["accounts.id=?", self])
end
No probado, pero debería funcionar para una asociación HABTM o has_many :through
. Hay algunas optimizaciones que puede hacer con la consulta según el enfoque que elija.
Algún día podríamos obtener soporte para <=> profundamente anidado que manejaría algo de esto.
Otros consejos
Esto podría ser útil para usted (Rails 2.x)