Pergunta

Eu estou trabalhando em um aplicativo desenvolvido usando o Zend Framework. Defini relações em modelos, e pode usá-los felizes, por exemplo:

$rowset = $row->findManyToManyRowset('People', 'Jobs');

No entanto, eu bati um problema em que o conjunto de linhas é retornado tem nomes de colunas que são os mesmos em 'Pessoas' e 'Jobs' e, portanto, se funde as chaves do array, perder alguns dos dados do conjunto de linhas final.

Eu entendo que eu posso passar um objeto Zend_Db_Select para findManyToManyRowset() como um dos parâmetros, mas não consigo encontrar nenhuma documentação explicando como usá-lo neste caso, por exemplo .:

$select = $this->select()->from(array(
                                     'p' => 'people', 
                                     'j' => 'jobs'
                                     ),
                                array( 
                                     'person_id' => 'p.id',
                                     'job_id' => 'j.id',
                                     'person_code' => 'p.code',
                                     'job_code' => 'j.code'
                                     )
                                );  

Se eu tentar usar o código acima, eu recebo uma mensagem como:

Error: No reference rule "" from table People to table Jobs

Alguém pode me esclarecer sobre como isso deve ser feito? Eu sei que eu poderia mudar meus nomes de coluna no banco de dados, mas eu prefiro uma alteração de código ao invés de re-projetar a minha estrutura DB e atualizar todo o código relacionado.

Nota: sem alguma forma de aliasing coluna como acima, o conjunto de linhas retornado é assim (ou seja, ele funde-se as colunas com os mesmos nomes.):

[_data:protected] => Array
    (
        [id] => 1
        [code] => SX342
    )

Cheers,
Matt

Foi útil?

Solução

A minha primeira recomendação é que você não deve nomear colunas tais nomes genéricos como id e code. Estes nomes são sem sentido, e como você descobriu que eles também resultar em colisões quando você buscar resultados em uma matriz associativa.

Você também está usando a interface Select incorretamente. Você deve especificar somente uma tabela por chamada from() ou chamada join().

Finalmente, eu nunca tentar fazer consultas complexas através da interface relações Zend_Db_Table. É destinado somente para casos simples. Se você tiver uma consulta mais complexa, basta escrever a consulta SQL explicitamente.

Veja também Como fazer uma consulta se juntou na interface tabelas ZF?

Outras dicas

Eu sei que esta resposta vem um pouco tarde, mas aqui estão algumas coisas a apontar.

1) findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule, $matchRefRule, $select); -. Se você estiver passando um Zend_Db_Table_Select você vai querer passar null para as regras

2) O Zend_Db_Table_Select passado para o findManyToManyRowset() deve ser criado a partir $matchTable e é seguro supor que na onde cláusulas i é o alias para a tabela de intersecção, e m é o alias para a tabela de jogo.

3) No caso de colisões, m vai ganhar o nome da chave no retorno do array associativo em php. A consulta executada esta aparência:

  SELECT 
    `i`.*, `m`.* 
  FROM 
    `interscetTable` AS `i` 
  INNER JOIN 
    `matchTable` AS `m` 
  ON
    `i`.`fk_m` = `m`.`pk` WHERE (`i`.`fk_o` = ?)  

4) Não importa o que, o valor de retorno de findManyToManyRowset() será um conjunto de linhas criado a partir da $matchTable assim, se você precisa para capturar qualquer informação a partir da tabela de interseção, ao mesmo tempo, capturando os dados para a tabela de jogo, você provavelmente terá ter um Zend_Db_Select costume e evite usar o material Zend_Db_Table para mapear os dados de qualquer maneira.

Assim, um exemplo de trabalho, usando "People" como a tabela de jogo, "trabalhadores" como tabela de intersecção e vamos dizer "Clientes" como a tabela de origem .. Supondo que para este exemplo que as tabelas de unir algo como: People.id:... -> workers.person_id:client_id:job_id -> clientes: id:...

$client = $clientTable->fetchRow(); /// grab a random client

// fetch all people that have worked for the client ordered by their last name.
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('m.lastname')); 

// fetch all people that have worked for the client ordered by their hire date:
// `workers`.`hiredate`
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('i.hiredate')); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top