Implementación de relaciones de objetos en Parse y React
15 min
relaciones introducción usando parse, puedes almacenar objetos de datos estableciendo relaciones entre ellos para modelar este comportamiento, cualquier \<font color="#2166ae">parseobject \</font> puede ser utilizado como un valor en otros \<font color="#2166ae">parseobject\</font> internamente, el marco de parse almacenará el objeto referido en un solo lugar, para mantener la consistencia eso puede darte un poder extra al construir y ejecutar consultas complejas hay tres tipos principales de relaciones \<font color="#2166ae">uno a muchos\</font> , donde un objeto puede estar relacionado con muchos otros objetos; \<font color="#2166ae">muchos a muchos\</font> , que puede crear muchas relaciones complejas entre muchos objetos \<font color="#2166ae">uno a uno\</font> , estableciendo relaciones directas entre dos objetos y solo ellos; hay dos formas de crear una \<font color="#2166ae">uno a muchos\</font> relación en parse (recomendado) la primera es usar los \<font color="#2166ae">parse pointers\</font> en la clase hija, que es la más rápida en tiempo de creación y consulta usaremos esto en esta guía la segunda es usar \<font color="#2166ae">arreglos\</font> de \<font color="#2166ae">parse pointers\</font> en la clase padre, lo que puede llevar a tiempos de consulta lentos dependiendo de su tamaño debido a este problema de rendimiento, solo usaremos ejemplos de punteros hay tres formas de crear una \<font color="#2166ae">muchos a muchos\</font> relación en parse (recomendado) el primero es usar \<font color="#2166ae">parse relations\</font> , que es el más rápido en tiempo de creación y consulta usaremos esto en esta guía el segundo es usar \<font color="#2166ae">arrays\</font> de \<font color="#2166ae">parse pointers\</font> lo que puede llevar a tiempos de consulta lentos dependiendo de su tamaño el tercero es usar \<font color="#2166ae">jointable\</font> donde la idea proviene de bases de datos clásicas cuando hay una relación de muchos a muchos, combinamos cada \<font color="#2166ae">objectid \</font> o \<font color="#2166ae">pointer\</font> de ambos lados juntos para construir una nueva tabla separada en la que se rastrea la relación en esta guía, implementarás una aplicación de registro de libros en react que contiene los tres tipos principales de asociaciones de datos aprenderás cómo crear y consultar relaciones de datos usando back4app y react en cualquier momento, puedes acceder a este proyecto a través de nuestros repositorios de github para revisar los estilos y el código completo repositorio de ejemplo de javascript https //github com/templates back4app/react js associations repositorio de ejemplo de typescript https //github com/templates back4app/react ts associations requisitos previos para completar este tutorial, necesitarás una aplicación react creada y conectada a back4app https //www back4app com/docs/react/quickstart si deseas ejecutar el proyecto de ejemplo de esta guía, deberías configurar la biblioteca https //ant design/ objetivo para realizar y demostrar relaciones de base de datos en react utilizando parse en un escenario realista 1 entendiendo la clase libro dado que en esta guía utilizaremos un ejemplo de aplicación de registro de libros, primero necesitas entender cómo se estructuran las relaciones de objetos en esta base de datos la clase de objeto principal que utilizarás es la \<font color="#2166ae">libro \</font> clase, que almacenará cada entrada de libro en el registro estas son las otras cuatro clases de objeto \<font color="#2166ae">editorial\</font> nombre de la editorial del libro, relación de uno a muchos con \<font color="#2166ae">libro\</font> ; \<font color="#2166ae">género\</font> género del libro, relación de uno a muchos con \<font color="#2166ae">libro\</font> ten en cuenta que para este ejemplo consideraremos que un libro solo puede tener un género; \<font color="#2166ae">autor\</font> autor del libro, relación de muchos a muchos con \<font color="#2166ae">libro\</font> , ya que un libro puede tener más de un autor y un autor puede tener más de un libro también; \<font color="#2166ae">isdb\</font> número identificador isdb del libro, relación de uno a uno con \<font color="#2166ae">libro\</font> , ya que este número es único para cada libro aquí hay una representación visual de estas tablas de base de datos para simplificar, asumiremos que cada clase de objeto tiene solo un tipo de cadena \<font color="#2166ae">nombre\</font> atributo ( \<font color="#2166ae">título \</font> para el \<font color="#2166ae">libro\</font> ), además de cualquier atributo relacional adicional paso 2 creando relaciones antes de entrar en este paso, te recomendamos clonar y ejecutar el ejemplo de la aplicación react ( repositorio de ejemplo de javascript https //github com/templates back4app/react js associations , repositorio de ejemplo de typescript https //github com/templates back4app/react ts associations ) esta aplicación tiene dos pantallas principales una responsable de listar los libros registrados y la otra de crear nuevos libros en el formulario de registro de libros, hay enlaces directos a los otros objetos relacionados y un campo de entrada de texto asignado al valor isbd del libro, que se utilizará para crear la relación uno a uno echemos un vistazo al método de creación de libros que se llama al enviar este formulario 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 // radiogroup 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 // one to one (1 1) 26 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 27 let isbdquery = new parse query('isbd'); 28 isbdquery equalto('name', bookisbdvalue); 29 let isbdqueryresult = await isbdquery first(); 30 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 31 // if first returns a valid object instance, it means that there 32 // is at least one instance of isbd with the informed value 33 alert( 34 'error! 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 (1\ n) 47 // one to many relations can be set in two ways 48 // add direct object to field (parse will convert to pointer on save) 49 book set('publisher', bookpublisherobject); 50 // or add pointer to field 51 book set('genre', bookgenreobject topointer()); 52 53 // many to many (n\ n) 54 // create a new relation so data can be added 55 let authorsrelation = book relation('authors'); 56 // bookauthorsobjects is an array of parse objects, 57 // you can add to relation by adding the whole array or object by object 58 authorsrelation add(bookauthorsobjects); 59 60 // after setting the values, save it on the server 61 try { 62 await book save(); 63 // success 64 alert('success!'); 65 // navigate back to home screen using react router 66 history push('/'); 67 return true; 68 } catch (error) { 69 // error can be caused by lack of internet connection 70 alert(`error! ${error message}`); 71 return false; 72 } 73 } catch (error) { 74 // error can be caused by lack of value selection 75 alert( 76 'error! make sure to select valid choices in publisher, genre and author fields!', 77 ); 78 return false; 79 } 80 }; typescript 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 // one to one (1 1) 26 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 27 let isbdquery parse query = new parse query('isbd'); 28 isbdquery equalto('name', bookisbdvalue); 29 let isbdqueryresult parse object = await isbdquery first(); 30 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 31 // if first returns a valid object instance, it means that there 32 // is at least one instance of isbd with the informed value 33 alert( 34 'error! 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 (1\ n) 47 // one to many relations can be set in two ways 48 // add direct object to field (parse will convert to pointer on save) 49 book set('publisher', bookpublisherobject); 50 // or add pointer to field 51 book set('genre', bookgenreobject topointer()); 52 53 // many to many (n\ n) 54 // create a new relation so data can be added 55 let authorsrelation = book relation('authors'); 56 // bookauthorsobjects is an array of parse objects, 57 // you can add to relation by adding the whole array or object by object 58 authorsrelation add(bookauthorsobjects); 59 60 // after setting the values, save it on the server 61 try { 62 await book save(); 63 // success 64 alert('success!'); 65 // navigate back to home screen using react router 66 history push('/'); 67 return true; 68 } catch (error) { 69 // error can be caused by lack of internet connection 70 alert(`error! ${error message}`); 71 return false; 72 } 73 } catch (error) { 74 // error can be caused by lack of value selection 75 alert( 76 'error! make sure to select valid choices in publisher, genre and author fields!', 77 ); 78 return false; 79 } 80 }; ahora veamos por separado cómo se realizan los tres tipos de asociaciones al crear el \<font color="#2166ae">libro \</font> objeto relación uno a muchos nota cómo el \<font color="#2166ae">bookpublisherobject \</font> y \<font color="#2166ae">bookgenreobject\</font> se establecen en el nuevo libro \<font color="#2166ae">parse object\</font> instancia ve lo simple que es en parse crear una relación uno a muchos podrías asignar la instancia del objeto objetivo o un puntero a ella usando el \<font color="#2166ae">parse object set \</font> método, que toma dos argumentos el nombre del campo y el valor a establecer parse creará una columna de tipo de dato puntero y un enlace directo en tu panel para un acceso rápido en segundo plano relación muchos a muchos mira cómo se establecen los \<font color="#2166ae">bookauthorsobjects \</font> en la nueva instancia de libro \<font color="#2166ae">parse object\</font> para crear una relación muchos a muchos, primero necesitas crear un nuevo \<font color="#2166ae">parse object relation\</font> y luego agregar los objetos relacionados a él, ya sea uno por uno o pasando un array de \<font color="#2166ae">parse object\</font> usando el \<font color="#2166ae">parse object relation add\</font> método parse creará una columna de tipo relación y también una tabla relacional en tu base de datos parse también creará un enlace para un fácil acceso a esta nueva tabla en la columna de campo en el panel relación uno a uno vea cómo se establece el \<font color="#2166ae">bookisbdvalue \</font> en el nuevo libro \<font color="#2166ae">parse objec\</font> t crear y guardar relaciones uno a uno y uno a muchos en parse son procesos similares, en los que pasas como argumento la \<font color="#2166ae">parse object \</font> instancia usando el \<font color="#2166ae">parse object set\</font> método, que toma dos argumentos el nombre del campo y el valor a establecer el problema aquí es que, antes de guardar, necesitas asegurarte de que no hay \<font color="#2166ae">isbd\</font> objetos que contengan el valor de cadena de id isbd informado en tu base de datos y que no haya \<font color="#2166ae">book \</font> objetos ya relacionados con él también la segunda parte siempre será verdadera en este caso, ya que estás creando un nuevo \<font color="#2166ae">book \</font> objeto cada vez hacer cumplir la \<font color="#2166ae">isbd \</font> unicidad se puede lograr utilizando la siguiente consulta resaltada 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( 8 'error! there is already an isbd instance with this value!', 9 ); 10 return false; 11 } typescript 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( 8 'error! there is already an isbd instance with this value!', 9 ); 10 return false; 11 } después de guardar tus objetos con éxito, parse creará una columna de tipo de dato puntero y un enlace directo en tu panel de control también 3 consultando relaciones consultar objetos relacionados es bastante sencillo, ya que gran parte de ello es manejado por parse eche un vistazo a la función de consulta en la pantalla de lista de registros del libro y después destacaremos cómo se consulta cada tipo de relación 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(`error! ${error message}`); 49 return false; 50 } 51 }; typescript 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(`error! ${error message}`); 49 return false; 50 } 51 }; consulta uno a muchos para consultar cualquier libro relacionado con un editor o género específico, necesitas realizar un \<font color="#2166ae">parse query equalt\</font> método pasando la \<font color="#2166ae">parse object\</font> instancia como parámetro después de consultar, parse almacenará dentro de los objetos resultantes las instancias completas de cualquier campo relacional de uno a muchos para recuperar y mostrar datos de estas instancias de objeto, puedes encadenar el \<font color="#2166ae">parse object get\</font> método así \<font color="#2166ae">bookparseobject get(('publisher') get('name') \</font> consulta de muchos a muchos para consultar cualquier libro relacionado con un autor específico, la consulta también utilizará solo un \<font color="#2166ae">parse query equalto\</font> método sin embargo, después de consultar, parse no almacenará \<font color="#2166ae">parse object\</font> instancias de campos relacionales de muchos a muchos, solo una referencia al nombre de la clase relacionada, como \<font color="#2166ae">{" type" "relation", "classname" "author"}\</font> para recuperar y mostrar datos de estas instancias de objeto, necesitas crear una relación y consultarla nuevamente, almacenando los resultados en un arreglo de objetos propio consulta de uno a uno al igual que antes, para consultar cualquier libro relacionado con un isbd específico, necesitas realizar un \<font color="#2166ae">parse query equalto\</font> método pasando la \<font color="#2166ae">parse object\</font> instancia como parámetro después de consultar, parse almacenará dentro de los objetos resultantes las instancias completas de cualquier campo relacional de uno a uno, de la misma manera que se hace con los campos relacionales de uno a muchos conclusión al final de esta guía, aprendiste cómo crear y consultar relaciones en parse en react en la próxima guía, te mostraremos cómo registrar usuarios