Pregunta

tengo un n...n estructura para dos mesas, makes y models.Hasta ahora no hay problema.

En una tercera mesa (products) como:

id
make_id
model_id
...

Mi problema es crear una vista para productos de un específico. make dentro de mi ProductsController que contiene solo eso es hacer modelos:

Pensé que esto podría funcionar:

var $uses = array('Make', 'Model');

$this->Make->id = 5; // My Make

$this->Make->find(); // Returns only the make I want with it's Models (HABTM)
$this->Model->find('list'); // Returns ALL models
$this->Make->Model->find('list'); // Returns ALL models

Entonces, si quiero usar el list para pasar a mi vista para crear botones de radio tendré que hacer un foreach() en mi make matriz para encontrar todos los títulos de los modelos y crear una nueva matriz y enviarla a la vista a través de $this->set().

$makeArray = $this->Make->find();
foreach ($makeArray['Model'] as $model) {
    $modelList[] = $model['title'];
}
$this->set('models', $models)

¿Existe alguna manera más fácil de obtener esa lista sin enfatizar el make Formación.Será una tarea común desarrollar tales escenarios en mis aplicaciones.

¡Gracias de antemano por cualquier pista!

¿Fue útil?

Solución 5

La solución se puede lograr con el uso de la with operación en matriz habtm en el modelo.

Usando with puedes definir la tabla "intermedia" como:

$habtm = " ...
  'with' => 'MakeModel',
   ... ";

Y internamente, en el Modelo o Controlador, puedes emitir condiciones al find método.

Ver: http://www.cricava.com/blogs/index.php?blog=6&title=modelizing_habtm_join_tables_in_cakephp_&more=1&c=1&tb=1&pb=1

Otros consejos

Aquí está mi pista:Intente escribir su consulta en SQL normal antes de intentar reconstruirla utilizando la biblioteca Cake.En esencia, estás haciendo mucho trabajo adicional que la base de datos puede hacer por ti.Su enfoque (solo para mostrar, no es un buen SQL):

SELECT * FROM makes, models, products WHERE make_id = 5

No estás tomando en consideración las relaciones (a menos que Cake entienda automáticamente las relaciones de las tablas)

Probablemente estés buscando algo que una estas cosas:

SELECT models.title FROM models 
INNER JOIN products 
  ON products.model_id = models.model_id 
  AND products.make_id = 5

¿Ojalá esto sea un empujón en la dirección correcta?

A juzgar por su comentario, lo que está preguntando es cómo obtener resultados de un modelo determinado, donde la condición está en un modelo relacionado con HABTM.Es decir.algo que normalmente harías con una declaración JOIN en SQL sin formato.
Actualmente ese es uno de los pocos puntos débiles de Cake.Hay diferentes estrategias para lidiar con eso.

  • Haga que el modelo B relacionado devuelva todos los identificadores de posibles candidatos para el Modelo A y luego realice una segunda consulta en el Modelo A.Es decir.:

    $this->ModelB->find('first', array('conditions' => array('field' => $condition)));
    array(
        ['ModelB'] => array( ... ),
        ['ModelA'] => array(
            [0] => array(
                'id' => 1
            )
    )
    

    Ahora tiene una matriz de todos los identificadores de ModelA que pertenecen a ModelB que coinciden con sus condiciones, que puede extraer fácilmente usando Set::extract().Básicamente el equivalente a SELECT model_a.id FROM model_b JOIN model_a WHERE model_b.field = xxx.A continuación buscas ModelA:

     $this->ModelA->find('all', array('conditions' => array('id' => $model_a_ids)));
    

    eso producirá SELECT model_a.* FROM model_a WHERE id IN (1, 2, 3), que es una forma indirecta de hacer la declaración JOIN.Si necesita condiciones en más de un modelo relacionado, repita hasta que tenga todos los identificadores para el Modelo A, SQL usará la intersección de todos los identificadores (WHERE id IN (1, 2, 3) AND id IN (3, 4, 5)).

  • Si solo necesita una condición en ModelB pero desea recuperar ModelA, simplemente busque ModelB.Cake recuperará automáticamente los ModelA relacionados (ver arriba).Es posible que necesite Set::extract() nuevamente, pero es posible que eso ya sea suficiente.

  • Puede utilizar el método anterior y combinarlo con el Comportamiento contenible para tener un mayor control sobre los resultados.

  • Si todo lo demás falla o los métodos anteriores simplemente producen demasiada sobrecarga, aún puedes escribir tu propio SQL sin formato con $this->Model->query().Si sigue los estándares Cake SQL (nombrar tablas correctamente con FROM model_as AS ModelA) Cake seguirá procesando tus resultados correctamente.

Espero que esto te lleve en la dirección correcta.

Todas sus diferentes llamadas Make->find() y Model->find() son completamente independientes entre sí.Incluso Make->Model->find() es lo mismo que Model->find(), Cake no recuerda ni tiene en cuenta de ninguna manera lo que ya ha encontrado en otros modelos.Lo que estás buscando es algo como:

$this->Product->find('all', array('conditions' => array('make_id' => 5)));

Consulte el método Set::extract() para obtener una lista de títulos de modelos a partir de los resultados de $this->Make->find()

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top