ror rails formularios formulario anidados ruby-on-rails-4 rails-activerecord active-record-query

ruby-on-rails-4 - rails - scaffold ror



Consulta ActiveRecord a travĂ©s de mĂșltiples uniones (4)

Asumiendo managers es un nombre modelo

managers.find(:all, :joins=>" JOIN stores ON stores.manager_id = managers.id JOIN regions ON stores.region_id = regions.id JOIN readings ON readings.region_number = regions.number" :conditions=>"manager.name = ''John Smith'' AND regions.number = ''1234567''" :limit=>100)

Tengo un esquema como este.

managers has_many :emails has_many :stores emails belongs_to :manager stores belongs_to :manager belongs_to :region regions has_many :stores has_many :readings readings belongs_to :regions

Quiero obtener lecturas para un gerente. En SQL haría algo como esto.

SELECT * FROM managers JOIN stores ON stores.manager_id = managers.id JOIN regions ON stores.region_id = regions.id JOIN readings ON readings.region_number = regions.number WHERE manager.name = ''John Smith'' AND regions.number = ''1234567'' LIMIT 100

No puedo averiguar cómo hacer esto en activerecord. He estado tratando de darle sentido a http://guides.rubyonrails.org/active_record_querying.html y http://guides.rubyonrails.org/association_basics.html pero no se está hundiendo. Creo que solo necesito verlo desde Un punto de vista diferente.

Estaba pensando que estaría accediendo a los datos de esta manera pero creo que simplemente no entiendo cómo funciona.

managers.name managers.stores.name managers.stores.regions.readings.limit(10)

He estado teniendo que hacer algo como esto que es mucho más feo.

managers.first.stores.first.regions.first.readings.limit(10)


Considere los siguientes modelos (y el uso de has_many a través):

class Reading < ActiveRecord::Base belongs_to :region, inverse_of: :readings end class Region < ActiveRecord::Base has_many :readings, inverse_of: :region has_many :stores, inverse_of: :region end class Store < ActiveRecord::Base belongs_to :region, inverse_of: :stores belongs_to :manager, inverse_of: :stores end class Manager < ActiveRecord::Base has_many :stores, inverse_of: :region has_many :emails, inverse_of: :manager has_many :regions, through: :stores has_many :readings, through: :regions end class Email < ActiveRecord::Base belongs_to :manager, inverse_of: :emails end

Ahora su pregunta es un poco ambigua porque dice que desea obtener lecturas para un administrador, pero su SQL no selecciona las lecturas en absoluto y también prescribe una región.

Suponiendo que desea que todas las Lecturas coincidan con un Administrador y una Región dados:

@readings = Reading.joins(region: { stores: :manager }).where( manager: { name: ''John Smith'' }, region: { id: 1234567 })

Suponiendo que también desea cargar regiones, almacenes y administradores para evitar las consultas 1 + N:

@readings = Reading.includes(region: { stores: :manager }).where( manager: { name: ''John Smith'' }, region: { id: 1234567 })

Suponiendo que tenga un nombre de administrador y desee tanto sus detalles como sus lecturas:

@manager = Manager.where(name: ''John Smith'').first! @readings = manager.readings

Todos los ejemplos de consulta anteriores devuelven ActiveRecord::Relation ''s, que puede encadenarse aún más where condiciones, o las joins , el limit , el group , el having y el order etc.

También debe considerar las diferencias de los métodos de eager_load , eager_load , preload , eager_load y references . Aquí hay un resumen sobre ellos here también lo alentaría a leer documentos, guías y blogs sobre Arel, ya que también es compatible con las uniones y los alias.

Después de usar ActiveRecord en ira por un tiempo, he llegado a la conclusión de que Sequel / SequelModel es un DB / ORM mucho mejor que ActiveRecord. No hay falta de respeto a los desarrolladores, pero he encontrado que Sequel es una mejor herramienta. Arel tiene poca documentación desde hace años y ActiveRecord / Arel tiene fallas en varias áreas, como condiciones de unión, control de tipos de unión y carga impaciente, uniones, intersecciones, consultas recursivas, árboles / listas de adyacencia y muchas otras características de SQL que Secuela cubre

Como parece que recién está comenzando con AR, tal vez desee comenzar con Sequel en lugar de luchar con las debilidades y las frustraciones de las consultas de ActiveRecord, incluido el uso inconexo de AR y Arel, Relaciones vs Asociaciones y rarezas en la composición de consultas, continúa y en. No hay nada más frustrante que saber el SQL que desea, pero ActiveRecord / Arel conspiran para detenerlo, por lo que se ven obligados a usar la ruta de escape promocionada y ''solo use el fragmento de cadena SQL'' y obtiene un resultado que no se puede encadenar , pero el resto de tu código espera una relación! (por ejemplo, resultados paginados)


Quería comentar sobre el comentario del usuario1757006 del 4 de octubre de 13 a las 14:39 , pero no tengo suficientes puntos. De todos modos, esto aborda escenarios de anidación más profundos. He agregado modelos de planetas y países para mostrar cómo funciona la sintaxis cuando se necesitan encadenar modelos adicionales.

@readings = Reading.includes(planet: [ country: [ region: [ {stores: :manager}]]]).where( manager: { name: ''John Smith'' }, region: {id: 1234567 })


prueba algo como esto:

managers.joins(stores: {regions: :readings}).where(''managers.name = ? AND regions.number = ?'', ''John Smith'', ''1234567'').limit(100)