1:1 Relationship
9 分
一対一の関係 はじめに 多くのバックエンドの中心には、データを保存する能力があります。parseを使用すると、データオブジェクトを保存し、それらの間に関係を確立できます。データ関係は、各データオブジェクトが他のオブジェクトとどのように関連または関連付けられているかを標準化します。これにより、複雑なクエリを構築および実行する際に追加の力を得ることができます。主な関係のタイプは3つあります \<font color="#2166ae">一対多\</font> , 1つのオブジェクトが多くの他のオブジェクトに関連付けられる場合; \<font color="#2166ae">一対一\</font> , 2つのオブジェクトの間に直接的な関係を確立し、それだけである場合; \<font color="#2166ae">多対多\</font> , 多くのオブジェクト間に多くの複雑な関係を作成することができます。 このガイドでは、1対1の関係に焦点を当てます。これらの関係は、id番号や電話番号など、強制する必要のある一意のフィールドを必要とするセンシティブなデータとユーザー管理を含むアプリケーションで一般的です。データストレージバックエンドは通常、これらの関連付けの明示的な宣言を要求し、parseにはそのような関連付けを達成するための自動的な解決策はありません。 ただし、サーバー上で \<font color="#2166ae">parse cloud\</font> 関数を使用することで、parseで1 1の関係を実装する方法があります。これにより、データを保存する前にテーブルの関係が一意であることが強制されます。これは、関連するクラスの両方に \<font color="#2166ae">beforesave\</font> 関数を作成し、親クラスが子クラスにすでに1つのインスタンスを持っている場合は保存を防ぎ、逆も同様です。 また、アプリケーションのparseコードでこれらのケースを処理し、保存する前にサーバーをクエリして、関係を保証することもできます。これはこのガイドで示す方法ですが、クラウド関数を使用する方がはるかにクリーンで推奨されます。 このガイドでは、3つの主要なデータ関連を含むreact nativeの書籍登録アプリケーションを実装します。back4appとreact nativeを使用して、1対1のデータ関係を作成し、クエリする方法を学びます。 いつでも、スタイルや完全なコードを確認するために、私たちのgithubリポジトリを通じてこのプロジェクトにアクセスできます。 javascriptの例リポジトリ https //github com/templates back4app/react native js associations typescriptの例リポジトリ https //github com/templates back4app/react native ts associations 前提条件 このチュートリアルを完了するには、次のものが必要です: 作成され、 back4app https //www back4app com/docs/react native/parse sdk/react native sdk に接続されたreact nativeアプリ。 このガイドで提供されている画面レイアウトをテスト/使用したい場合は、 \<font color="#2166ae">react native paper\</font> を設定する必要があります。 ライブラリ https //github com/callstack/react native paper 目標 リアルなシナリオでparseを使用して、react nativeにおける1対1のデータベース関係を実行し、デモンストレーションすること。 1 bookクラスの理解 このガイドでは書籍登録アプリケーションの例を使用するため、まずこのデータベースにおけるオブジェクト関係がどのように構成されているかを理解する必要があります。使用する主なオブジェクトクラスは、 \<font color="#2166ae">book\</font> クラスで、登録内の各書籍エントリを保存します。以下は他の4つのオブジェクトクラスです \<font color="#2166ae">publisher\</font> 書籍出版社名、 \<font color="#2166ae">book\</font> との一対多の関係です。 \<font color="#2166ae">genre\</font> 書籍のジャンル、 \<font color="#2166ae">book\</font> との一対多の関係です。この例では、書籍は1つのジャンルしか持てないと考えます。 \<font color="#2166ae">author\</font> 書籍の著者、 \<font color="#2166ae">book\</font> との多対多の関係です。書籍は複数の著者を持つことができ、著者も複数の書籍を持つことができます。 \<font color="#2166ae">isdb\</font> 書籍のisdb識別番号、 \<font color="#2166ae">book\</font> との一対一の関係です。この番号は各書籍に対してユニークです。 これらのデータベーステーブルの視覚的表現は次のとおりです 簡単のために、各オブジェクトクラスが文字列型の \<font color="#2166ae">名前\</font> 属性( \<font color="#2166ae">タイトル\</font> )を持つと仮定します。 \<font color="#2166ae">本\</font> に関しては、追加のリレーショナル属性はありません。 2 一対多の関係を作成する このステップに進む前に、react nativeライブラリアプリの例をクローンして実行することをお勧めします( javascript例リポジトリ https //github com/templates back4app/react native js associations , typescript例リポジトリ https //github com/templates back4app/react native ts associations )。このアプリケーションには、登録された本をリストするための画面と、新しい本を作成するための画面の2つの主要な画面があります。本の登録フォームには、他の関連オブジェクトへの直接リンクと、本のisbd値に割り当てられた \<font color="#2166ae">textinput\</font> フィールドがあります。これは、一対一の関係を作成するために使用されます。 このフォームを送信するときに呼び出される本の作成メソッドを見てみましょう 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 }; 新しい本の \<font color="#2166ae">bookisbdvalue\</font> が設定されているのを見てください \<font color="#2166ae">parse object\</font> インスタンス。parseでの一対一および一対多の関係を作成して保存するプロセスは似ており、引数として \<font color="#2166ae">parse object\</font> インスタンスを渡します。 \<font color="#2166ae">parse object set\</font> メソッドを使用し、これは2つの引数を取ります:フィールド名と設定する値です。 ここでのポイントは、保存する前に、データベース内に通知された isbd id 文字列値を含む \<font color="#2166ae">isbd\</font> オブジェクトが存在しないことを確認し、さらにそれに関連する \<font color="#2166ae">book\</font> オブジェクトも存在しないことを確認する必要があります。この場合、2 番目の部分は常に真であり、毎回新しい \<font color="#2166ae">book\</font> オブジェクトを作成しているためです。 \<font color="#2166ae">isbd\</font> の一意性を強制するには、以下のハイライトされたクエリを使用できます 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 } オブジェクトを正常に保存した後、parseはポインタデータ型のカラムを作成し、ダッシュボードに直接リンクを作成して、内部で迅速にアクセスできるようにします。 3 一対一の関係をクエリする 1対1の関連オブジェクトをクエリするのは非常に簡単で、ほとんどがparseによって処理されます。本の登録リスト画面のクエリ関数を見てみましょう 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 }; この場合、特定のisbdに関連する書籍をクエリするには、次のように実行するだけです。 \<font color="#2166ae">parse query equalto\</font> メソッドに \<font color="#2166ae">parse object\</font> インスタンスをパラメータとして渡します。クエリの後、parseは結果のオブジェクト内に一対一のリレーショナルフィールドの完全なインスタンスを保存します。これらのオブジェクトインスタンスからデータを取得して表示するには、次のように \<font color="#2166ae">parse object get\</font> メソッドをチェーンします。次のようになります \<font color="#2166ae">bookparseobject get(('isbd') get('name')\</font> ここに、これらのゲッターを使用してリストアイテムからisbd名を取得するリスト画面の見た目があります 結論 このガイドの最後に、react nativeでparseの一対一の関係を作成し、クエリする方法を学びました。次のガイドでは、ユーザーを登録する方法を示します。