Como corrigir o Relationship Field no ACF PRO
O que é Relationship Field do ACF PRO que não funciona?
O Relationship field do ACF PRO é o campo de seleção dupla que liga um post a outros posts, páginas ou custom post types. Quando ele não funciona, o sintoma cai em três famílias: a seleção não salva no editor, o template imprime branco ou erro em vez dos posts ligados, ou uma busca por quem aponta para um post não retorna resultado. O ponto que confunde é que o valor é guardado serializado na wp_postmeta, no formato a:2:{i:0;s:2:”35″;i:1;s:2:”33″;}, e o que o get_field() devolve depende do Return Format do campo (objeto WP_Post ou ID inteiro). Misturar esses dois mundos, ou esquecer de restaurar o post global depois do loop, é o que quebra o campo na prática, sem gerar erro fatal.
Como identificar
- No template, o bloco que deveria listar os posts ligados renderiza em branco, mesmo com itens selecionados no editor.
- var_dump( get_field(‘posts_relacionados’) ) imprime bool(false) ou array vazio em vez dos posts esperados.
- Depois do laço do relationship, o resto da página mostra o título e o link de um dos posts relacionados no lugar do post principal.
- Aviso Trying to get property ID of non-object ou Object of class WP_Post could not be converted no log, ao acessar o item do array.
- Uma WP_Query que busca quem referencia um post pelo relationship retorna zero posts, mesmo havendo ligações salvas.
- Ao tentar salvar, o ACF exibe a validação de mínimo ou máximo de posts e a seleção é descartada.
Como prevenir
- Defina o Return Format do relationship logo na criação do campo e escreva o loop do template no mesmo formato, evitando o descompasso objeto contra ID.
- Encerre todo loop que usa setup_postdata com wp_reset_postdata, padronizando isso em todos os templates que listam posts relacionados.
- Ao consultar o relationship por código, use sempre compare LIKE com o ID entre aspas e nunca igualdade exata, porque o valor vive serializado.
- Versione a pasta acf-json no tema para os field groups viajarem com o código e o field name sempre resolver em cada ambiente.
Causa
- O Return Format do campo está como Post Object e o template trata cada item como ID (ex.: passa o item direto para get_permalink esperando um número), ou o inverso: está como Post ID e o código acessa item->ID como se fosse objeto.
- O loop usa setup_postdata para imprimir cada relacionado mas não chama wp_reset_postdata ao final, então o post global fica apontando para o último relacionado e o restante da página sai trocado.
- A consulta que procura quais posts apontam para um alvo usa compare igual a igualdade exata no valor, mas o relationship é gravado serializado, então só compare LIKE com o ID entre aspas casa dentro do array serializado.
- O filtro Filter by Post Type, Filter by Post Status ou Filter by Taxonomy do campo está restringindo a coluna de escolha, então os posts que você espera ligar nem aparecem para seleção.
- A chamada usa o field key no formato field_5f3a1b2c em vez do field name do campo, e o grupo não está sincronizado, então o ACF não resolve o nome e devolve vazio.
- A regra de Minimum Posts ou Maximum Posts na aba de validação está sendo violada (zero selecionado num campo obrigatório, ou mais itens que o teto), e o ACF bloqueia o save da seleção.
Como resolver
- Veja o que o campo realmente devolve: No template, imprima o valor cru do campo no contexto onde ele falha. Isso revela se o retorno é uma lista de objetos WP_Post, uma lista de IDs, false ou vazio, e direciona toda a correção seguinte.
var_dump( get_field('posts_relacionados') ); - Alinhe o Return Format com o código do template: Decida um formato e siga ele. No painel do ACF abra o campo e ajuste o Return Format, depois escreva o loop correspondente. Caminho no menu: Custom Fields -> Field Groups -> seu grupo -> o campo -> Return Format.
Custom Fields -> Field Groups -> [grupo] -> [campo] -> Return Format $posts = get_field('posts_relacionados'); // Return Format = Post Object foreach ( $posts as $post ) { setup_postdata( $post ); the_title(); } - Restaure o post global ao fim do loop: Sempre que usar setup_postdata para imprimir os relacionados, feche o laço restaurando o post principal. Sem isso o resto da página herda o último relacionado.
wp_reset_postdata(); - Consulte o relationship com LIKE no valor serializado: Para buscar quais posts apontam para um alvo, não use igualdade exata: o valor é serializado. Use compare LIKE com o ID entre aspas, que casa o item dentro do array e evita falso positivo com IDs que são substring.
'meta_query' => array( array( 'key' => 'posts_relacionados', 'value' => '"' . $post_id . '"', 'compare' => 'LIKE' ) ) - Revise os filtros da coluna de escolha: Se os posts que você quer ligar nem aparecem para selecionar, são os filtros do campo restringindo a lista. Confira Filter by Post Type, Filter by Post Status e Filter by Taxonomy e deixe-os cobrindo o que precisa aparecer. Caminho no menu: Custom Fields -> Field Groups -> o campo -> Filters.
Custom Fields -> Field Groups -> [campo] -> Filter by Post Type / Post Status / Taxonomy - Cheque a validação de mínimo e máximo: Se a seleção some ao salvar, é a regra de quantidade barrando. Ajuste Minimum Posts e Maximum Posts na configuração do campo para a faixa real de uso. Caminho no menu: Custom Fields -> Field Groups -> o campo -> Validation.
Custom Fields -> Field Groups -> [campo] -> Minimum Posts / Maximum Posts
<?php
// Relationship com Return Format = Post Object: lista e restaura o post global.
$relacionados = get_field( 'posts_relacionados' );
if ( $relacionados ) {
echo '<ul>';
foreach ( $relacionados as $post ) {
setup_postdata( $post ); // habilita the_title()/the_permalink()
printf(
'<li><a href="%s">%s</a></li>',
esc_url( get_permalink() ),
esc_html( get_the_title() )
);
}
wp_reset_postdata(); // OBRIGATORIO: devolve o post principal
echo '</ul>';
}
// Busca reversa: quem aponta para $alvo_id (valor serializado -> compare LIKE).
$apontam = get_posts( array(
'post_type' => 'any',
'meta_query' => array( array(
'key' => 'posts_relacionados',
'value' => '"' . $alvo_id . '"',
'compare' => 'LIKE',
) ),
) );














