今日の作業の大部分は昨日からの作業の続きで、アプリケーションのルートにビジネス ロジックを実装するだけです。そこで、この件について書くのをやめて、アプリケーション内で非常に特殊なことを行うために作成した 3 つの関数について話したいと思いました。
これは、居場所を見つけるのが難しい小さな関数をすべて置くディレクトリですが、アプリケーションはこれらの関数なしでは生きていけません。
utils フォルダーは、多くのアプリケーションの縁の下の力持ちのゴミ捨て場です。
数行以上のコードを必要とし、再利用する必要があるデータの変換を実行する必要がある場合は、データを独自のファイルに入れて、アプリケーションの残りの部分。
コピペしてみませんか?これは、DRY と関心の分離という 2 つのプログラミング原則に違反することになります。
同じことを繰り返すのは単調であるだけでなく、アプリケーション全体で十分に行ったとしても変更するのは面倒です。今日の降水確率を計算するアルゴリズムを想像してください。
人々がどのようにそれを行うのかわからないので、例を示すことはできません。しかし、この計算にアクセスする必要があるさまざまな場所のコード全体にこれをコピーすると、非常にスマートな科学気象委員会が新しい、より正確なアルゴリズムを持って戻ってきたときに非常に動揺するでしょう。
コードの再利用部分を取り出し、それらを 1 か所で更新しながら複数の場所で使用できるようにパッケージ化する方法を見つけます。
utils フォルダー内の関数はすべて、アプリケーション全体のさまざまな場所で使用されています!
プログラマとして、私たちはさまざまなことを実行する関数を作成したくありません。むしろ、すべてが 1 つのことを実行する関数をたくさん用意したいと考えています。なぜ?そう、これによりこれらの関数がより再利用可能になります!
これは utils フォルダーと何の関係がありますか?さて、これから説明する関数は、実際には getRoastsById のような関数内に入る場所がありません。それは、実際には getRoastsById のような関数ではないからです。何か他のことをする必要があるときは、そのための関数を作成する必要があります。しかし、その関数を論理的に置く場所がないときは、それが「ヘルパー」であるため、それを utils ディレクトリに貼り付けます。
これまでに 3 つのカスタム ユーティリティがあります:
彼らの名前を見れば、彼らが何をするのかが明らかだと思いますが、彼らが解決する問題とその仕組みについて簡単に説明しましょう。
問題: アプリケーションのさまざまなサービスの多くで、データベースに対して INSERT クエリを実行する必要があります。これらのステートメントでは、1) 列の名前と 2) 値を明示的にリストする必要があります。これらを各ルートで入力する必要はないので、それを行う関数を作成しました。
Input: この関数は 2 つのパラメーターを受け取ります。table はデータベース内のテーブルの名前と一致する文字列で、obj はユーザーがデータベースに追加するモデルを表す Javascript オブジェクトです。
出力: 1) プレースホルダー値を含むプロパティ形式の INSERT 文字列、および 2) パラメーター化されたクエリで使用される値の配列を含むオブジェクト。
const { snakeCase } = require('change-case-commonjs'); function insertStatement(table, obj) { const keys = Object.keys(obj); const values = Object.values(obj); let statement = `INSERT INTO ${table} (`; // Add snake_case keys to the statement const keyString = keys.map((key, i) => snakeCase(key)).join(', '); statement = `${keyString}) VALUES (`; // Add placeholders for the values const placeholders = keys.map((_, i) => `$${i 1}`).join(', '); statement = `${placeholders}) RETURNING *;`; // Return the query string and the values array return { text: statement, values: values }; } module.exports = insertStatement;
問題: INSERT ステートメントと同様に、UPDATE ステートメントでは、クエリ内で列名と値の両方を明示的に指定する必要があります。この構文は INSERT ステートメントとは異なります。条件付きロジックを使用して、databaseQueryGenerator 関数を作成できますが、これも関心の分離に違反しているようです。そのような関数は、必要なクエリの種類を決定するのでしょうか、それともそれに基づいて構文を生成するのでしょうか?
Input: この関数は 3 つのパラメーターを取ります。 obj: 更新されたレコードを表す JavaScript オブジェクト。 table は、データベース内のテーブルと一致する文字列です。 id 、新しい情報で更新されるレコードに一致する整数。
出力: 1) プレースホルダー値を含むプロパティ形式の UPDATE 文字列、および 2) パラメーター化されたクエリで使用される値の配列を含むオブジェクト。
const { snakeCase } = require('change-case-commonjs'); function updateStatement(obj, table, id) { const keys = Object.keys(obj); const values = Object.values(obj); let statement = `UPDATE ${table} SET `; keys.forEach((key, index) => { statement = `${snakeCase(key)} = $${index 1}, `; }); // Remove the last comma and space statement = statement.slice(0, -2); // Determine the correct ID column based on the table const idColumn = table === 'users' ? 'username' : table === 'roasts' ? 'roast_id' : ''; // Finalize the statement with the WHERE clause statement = ` WHERE ${idColumn} = $${keys.length 1} RETURNING *;`; return { text: statement, values: [...values, id] }; } module.exports = updateStatement
問題: データベースのスタイルが JavaScript のスタイルと異なります。しかし、私はどちらの分野でも妥協するつもりはありません。私の JS ファイルでは、命名規則でキャメルケースが使用されていますが、データベースではスネークケースが使用されています。返されたオブジェクトのプロパティ名はすべて同じですが、形式が異なります。このケースの標準を維持するには、snake_case を使用して JS 内のプロパティにアクセスする必要がありますが、これは好きではありません。
Input: この関数は、キーをキャメルケース形式に変換する必要がある obj JavaScript オブジェクトというパラメーターを 1 つだけ取ります。
出力: キャメルケース形式のキーを持つ同じオブジェクト。
const { camelCase } = require('change-case-commonjs'); function objectKeysToCamel(obj) { // Extract the keys and values const keys = Object.keys(obj); const values = Object.values(obj); let camel = {} // Change the formatting of each key, assigning it the proper value keys.forEach((key, i) => { const camelKey = camelCase(key); camel[camelKey] = values[i] }) // Return the new object return camel; } module.exports = objectKeysToCamel;
変更を追いたい場合、ローカルでフォークして実行したい場合、さらにはコードの変更を提案したい場合は、GitHub リポジトリへのリンクをご覧ください。
https://github.com/nmiller15/roast
フロントエンド アプリケーションは現在 Netlify にデプロイされています。いくつかの機能を試して実際の動作を確認したい場合は、以下のモバイル デバイスで表示してください。
https://knowyourhomeroast.netlify.app
注: このデプロイメントにはバックエンド API がないため、アカウントとローストは実際にはセッション間のどこにも保存されません。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3