1:1 Relationship
11 min
relação um a um introdução no cerne de muitos backends, você encontrará a capacidade de armazenar dados usando o parse, você pode armazenar objetos de dados estabelecendo relações entre eles as relações de dados padronizam como cada objeto de dados está relacionado ou associado a outros isso pode lhe dar um poder extra ao construir e executar consultas complexas existem três tipos principais de relação \<font color="#2166ae">um para muitos\</font> , onde um objeto pode estar relacionado a muitos outros objetos; \<font color="#2166ae">um para um\</font> , estabelecendo relações diretas entre dois objetos e apenas eles; \<font color="#2166ae">muitos para muitos\</font> , que pode criar muitas relações complexas entre muitos objetos neste guia, focaremos em relações um a um essas relações são comuns em aplicações que envolvem dados sensíveis e gerenciamento de usuários, que requerem campos únicos que precisam ser impostos, como números de identificação e números de telefone os backends de armazenamento de dados geralmente exigem declarações explícitas dessas associações e o parse não possui uma solução automática para alcançar tais associações no entanto, existem maneiras de implementar relações 1 1 no parse usando \<font color="#2166ae">parse cloud\</font> funções em seu servidor, garantindo que as relações de tabela permaneçam únicas antes de salvar os dados isso é feito criando \<font color="#2166ae">beforesave\</font> funções em ambas as classes relacionadas e impedindo a gravação se a classe pai já possuir uma instância na classe filha, e vice versa você também pode tratar esses casos no código da sua aplicação parse, consultando o servidor antes de salvar e garantindo a referida relação este será o método mostrado neste guia, mas observe que usar funções em nuvem é muito mais limpo e mais aconselhável neste guia, você implementará uma aplicação de registro de livros em react native que contém os três principais tipos de associações de dados você aprenderá como criar e consultar relações de dados um a um usando back4app e react native a qualquer momento, você pode acessar este projeto através de nossos repositórios no github para conferir os estilos e o código completo repositório de exemplo em javascript https //github com/templates back4app/react native js associations repositório de exemplo em typescript https //github com/templates back4app/react native ts associations pré requisitos para completar este tutorial, você precisará um aplicativo react native criado e conectado a back4app https //www back4app com/docs/react native/parse sdk/react native sdk se você quiser testar/usar o layout de tela fornecido por este guia, você deve configurar o \<font color="#2166ae">react native paper\</font> biblioteca https //github com/callstack/react native paper objetivo realizar e demonstrar relações de banco de dados um para um no react native usando parse em um cenário realista 1 entendendo a classe livro como neste guia usaremos um exemplo de aplicação de registro de livros, você precisa primeiro entender como as relações de objetos estão dispostas neste banco de dados a principal classe de objeto que você usará é a \<font color="#2166ae">livro\</font> classe, que armazenará cada entrada de livro no registro estas são as outras quatro classes de objeto \<font color="#2166ae">editora\</font> nome da editora do livro, relação de um para muitos com \<font color="#2166ae">livro\</font> \<font color="#2166ae">gênero\</font> gênero do livro, relação de um para muitos com \<font color="#2166ae">livro\</font> note que para este exemplo consideraremos que um livro pode ter apenas um gênero; \<font color="#2166ae">autor\</font> autor do livro, relação de muitos para muitos com \<font color="#2166ae">livro\</font> , uma vez que um livro pode ter mais de um autor e um autor pode ter mais de um livro também; \<font color="#2166ae">isdb\</font> número identificador isdb do livro, relação de um para um com \<font color="#2166ae">livro\</font> , uma vez que este número é único para cada livro aqui está uma representação visual dessas tabelas de banco de dados para simplificar, vamos assumir que cada classe de objeto tem apenas um tipo de string \<font color="#2166ae">nome\</font> atributo ( \<font color="#2166ae">título\</font> para o \<font color="#2166ae">livro\</font> ), além de qualquer atributo relacional adicional 2 criando relações um para muitos antes de entrar neste passo, recomendamos que você clone e execute o exemplo do aplicativo da biblioteca react native ( repositório de exemplo em javascript https //github com/templates back4app/react native js associations , repositório de exemplo em typescript https //github com/templates back4app/react native ts associations ) este aplicativo tem duas telas principais uma responsável por listar os livros registrados e a outra por criar novos livros no formulário de registro de livros, há links diretos para os outros objetos relacionados e um \<font color="#2166ae">textinput\</font> campo atribuído ao valor isbd do livro, que será usado para criar sua relação um para um vamos dar uma olhada no método de criação de livros que é chamado ao enviar este formulário javascript 1 const createbook = async function () { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue = booktitle; 7 const bookisbdvalue = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiobutton group field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject = bookpublisher; 13 const bookgenreobject = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects = bookauthors; 17	 18 // creates a new parse object instance 19 let book = new parse object('book'); 20	 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24	 25 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 26 let isbdquery = new parse query('isbd'); 27 isbdquery equalto('name', bookisbdvalue); 28 let isbdqueryresult = await isbdquery first(); 29 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 30 // if first returns a valid object instance, it means that there 31 // is at least one instance of isbd with the informed value 32 alert alert( 33 'error!', 34 'there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45	 46 // one to many relations can be set in two ways 47 // add direct object to field (parse will convert to pointer on save) 48 book set('publisher', bookpublisherobject); 49 // or add pointer to field 50 book set('genre', bookgenreobject topointer()); 51	 52 // many to many relation 53 // create a new relation so data can be added 54 let authorsrelation = book relation('authors'); 55 // bookauthorsobjects is an array of parse objects, 56 // you can add to relation by adding the whole array or object by object 57 authorsrelation add(bookauthorsobjects); 58	 59 // after setting the values, save it on the server 60 try { 61 await book save(); 62 // success 63 alert alert('success!'); 64 navigation goback(); 65 return true; 66 } catch (error) { 67 // error can be caused by lack of internet connection 68 alert alert('error!', error message); 69 return false; 70 } 71 } catch (error) { 72 // error can be caused by lack of value selection 73 alert alert( 74 'error!', 75 'make sure to select valid choices in publisher, genre and author fields!', 76 ); 77 return false; 78 } 79 }; todolist tsx 1 const createbook = async function () promise\<boolean> { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue string = booktitle; 7 const bookisbdvalue string = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiobutton group field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject parse object = bookpublisher; 13 const bookgenreobject parse object = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects \[parse object] = bookauthors; 17	 18 // creates a new parse object instance 19 let book parse object = new parse object('book'); 20	 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24	 25 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 26 let isbdquery parse query = new parse query('isbd'); 27 isbdquery equalto('name', bookisbdvalue); 28 let isbdqueryresult parse object = await isbdquery first(); 29 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 30 // if first returns a valid object instance, it means that there 31 // is at least one instance of isbd with the informed value 32 alert alert( 33 'error!', 34 'there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd parse object = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45	 46 // one to many relations can be set in two ways 47 // add direct object to field (parse will convert to pointer on save) 48 book set('publisher', bookpublisherobject); 49 // or add pointer to field 50 book set('genre', bookgenreobject topointer()); 51	 52 // many to many relation 53 // create a new relation so data can be added 54 let authorsrelation = book relation('authors'); 55 // bookauthorsobjects is an array of parse objects, 56 // you can add to relation by adding the whole array or object by object 57 authorsrelation add(bookauthorsobjects); 58	 59 // after setting the values, save it on the server 60 try { 61 await book save(); 62 // success 63 alert alert('success!'); 64 navigation goback(); 65 return true; 66 } catch (error) { 67 // error can be caused by lack of internet connection 68 alert alert('error!', error message); 69 return false; 70 } 71 } catch (error) { 72 // error can be caused by lack of value selection 73 alert alert( 74 'error!', 75 'make sure to select valid choices in publisher, genre and author fields!', 76 ); 77 return false; 78 } 79 }; veja como o \<font color="#2166ae">bookisbdvalue\</font> está definido para o novo livro \<font color="#2166ae">parse object\</font> instância criar e salvar relações um para um e um para muitos no parse são processos semelhantes, nos quais você passa como argumento a \<font color="#2166ae">parse object\</font> instância usando o \<font color="#2166ae">parse object set\</font> método, que aceita dois argumentos o nome do campo e o valor a ser definido a questão aqui é que, antes de salvar, você precisa garantir que não haja \<font color="#2166ae">isbd\</font> objetos contendo o valor da string id isbd informado em seu banco de dados e que não haja \<font color="#2166ae">livro\</font> objetos já relacionados a ele também a segunda parte sempre será verdadeira neste caso, uma vez que você está criando um novo \<font color="#2166ae">livro\</font> objeto toda vez garantir a \<font color="#2166ae">unicidade do isbd\</font> pode ser alcançado usando a seguinte consulta destacada javascript 1 let isbdquery = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert alert( 8 'error!', 9 'there is already an isbd instance with this value!', 10 ); 11 return false; 12 } todolist tsx 1 let isbdquery parse query = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult parse object = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert alert( 8 'error!', 9 'there is already an isbd instance with this value!', 10 ); 11 return false; 12 } após salvar seus objetos com sucesso, o parse criará uma coluna do tipo de dado ponteiro e um link direto no seu painel para acesso rápido nos bastidores 3 consultando relações um para um consultar objetos relacionados um a um é bastante simples, pois grande parte disso é gerenciada pelo parse dê uma olhada na função de consulta na tela da lista de registros do livro javascript 1 const querybooks = async function () { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue = querypublisher; 8 const querygenrevalue = querygenre; 9 const queryauthorvalue = queryauthor; 10 const queryisbdvalue = queryisbd; 11	 12 // reading parse objects is done by using parse query 13 const parsequery = new parse query('book'); 14	 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22	 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27	 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33	 34 try { 35 let books = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert alert('error!', error message); 49 return false; 50 } 51 }; todolist tsx 1 const querybooks = async function () promise\<boolean> { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue parse object = querypublisher; 8 const querygenrevalue parse object = querygenre; 9 const queryauthorvalue parse object = queryauthor; 10 const queryisbdvalue parse object = queryisbd; 11	 12 // reading parse objects is done by using parse query 13 const parsequery parse query = new parse query('book'); 14	 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22	 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27	 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33	 34 try { 35 let books \[parse object] = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert alert('error!', error message); 49 return false; 50 } 51 }; neste caso, para consultar quaisquer livros relacionados a um isbd específico, você precisa apenas realizar um \<font color="#2166ae">parse query equalto\</font> método passando a \<font color="#2166ae">parse object\</font> instância como parâmetro após a consulta, o parse armazenará dentro dos objetos resultantes as instâncias completas de quaisquer campos relacionais um para um para recuperar e mostrar dados dessas instâncias de objeto, você pode encadear o \<font color="#2166ae">parse object get\</font> método assim \<font color="#2166ae">bookparseobject get(('isbd') get('name')\</font> aqui está como a tela da lista se parece ao usar esses getters para recuperar o nome do isbd dos itens da lista conclusão no final deste guia, você aprendeu como criar e consultar relações um para um no parse no react native no próximo guia, mostraremos como registrar usuários