JavaScriptとRailsシングルページアプリケーション


推測!
フロントエンドとRuby on Rails(“Rails”)としてバニラJavaScript(“js”)を使用して、単一のページアプリケーションを構築しました.
Github Link
Youtube Demo
ライブサイト

導入


私は、このプロジェクトが容易でないと言いたいです、実際に、このプロジェクトは私が持っていた最も難しいもののうちの1つでした.Railsで、すべてがとても単純で組織化されたように思えました、しかし、JavaScriptが来て、規則がないと私に示しました😩😂! JavaScriptを学ぶことは簡単な仕事でありません、そして、私には誰もこれまでに本当にJavaScriptまたはそれが可能であるすべてを知っている誰も信じない理由があります.私は常に自分がより多くのことを学ぶために別のプラットフォームに行くことを見つけた.JavaScriptの変数、関数、データ構造、hoisting、クロージャ、クラスの構文、および大いに多くを学んだ.
あなたがJavaScriptを学んでいるならば、私はこのコースを推薦します、それは私を大いに助けました. Javascript: Understanding The Weird Parts

計画


最初に、私は私のプロジェクトのための考えを思い起こさなければなりませんでした.私はデータベースを計画しなければならなかった.Drawで次のフローチャートを作成しました.入出力

私は、私のアプリケーションに多くのユーザーを持っていて、各ユーザーが多くのトレーニングをすることを望むということを知っていました.しかしながら、私は同じ日の下で複数のトレーニングをすることができたかったです、そして、私のインストラクターはそれのために結合テーブルを推薦しました、彼は賢い男性です.次のステップは私の計画を実行することでした.

RailsをAPIとして使う


以前のRuby on Railsアプリケーションの主な違いは、APIとしてのみ使用していたことです.つまり、次のコードを実行しなければならなかった.
$ rails new my_api --api
かつて私はRails APIを取得した、私は私が私のgemfileに必要な知っているいくつかの宝石を追加しました.最初の1つはgem 'rack-cors'であった.これはウェブアプリケーションがクロスドメインのAjax呼び出しを行うことを可能にする.ラックコーがどのように動作し、どのように実装するかについての詳しい情報は、 Ruby on Rails APIである.
一旦私の宝石がすべてセットアップされるならば、私は私の移行を作成して、シードされたデータをつくって、私のRESTfulルートをセットしました.Ruby on Railsを完全に構築したプロジェクトと、サーバーとして使用しているときの別の違いは、JSONとしてデータを返す必要があることです.たとえば、私のユーザーコントローラのインデックスメソッドは次のようになります.
class UsersController < ApplicationController
 def index
        user = User.all
        render json: user
    end
end
JSONをレンダリングしなければならないので、サーバーを走らせ、ブラウザでhereを訪問するとき、次のようなデータが表示されます.
{
    "users": [
      {
        "name": 1,
        "name": "Harry Potter",
      },
      {
        "id": 2,
        "name": "Courage The Cowardly Dog"
      }
    ]
  }
JSONデータは現在私にアクセス可能です、そして、私は現在私のバックエンドにフェッチ要求をすることができます.

メイキングhttp://localhost:3000/usersデータベースへのリクエスト


私のバックエンドから情報を得るために、私はFetch要求をしなければなりませんでした.最初に、私のサーバーが私のバックエンド(rails s)でターミナルを開いておくことによって走っていることを確認しました.次に、私のJointUserRangeトレーニングテーブルにfetchリクエストを作成するファイルを作成しました.
class WorkoutsAdapter {
    getWorkouts(){
        return fetch(`http://localhost:3000/api/v1/user_workouts`).then(res => res.json()
        )
    }

ページの反復とレンダリング


私の最大の課題


情報が返されると、情報を反復して日付順に並べたいと思ったので、次のコードを実行できました.
class Workouts{
    constructor(){
        this.workouts = {}
        this.adapter = new WorkoutsAdapter()
        this.fetchAndLoadWorkouts()  
    }
   fetchAndLoadWorkouts(){
        this.adapter.getWorkouts().then(workouts =>{
            workouts.forEach(workout => {
                if (this.workouts[workout.date]) {
                  this.workouts[workout.date].push(new Workout(workout))
                } else {
                    this.workouts = {...this.workouts, [workout.date]: [new Workout(workout)]}
                }

            })
        })
        .then(() =>{
            this.render()
        })
    }
上記のコードは、WorkoutsAdapterクラスおよびfetchDandloadWorksS ()関数への要求を行います.受け取った情報はトレーニングの配列です.その後、for_eachワークアウトは、日付がthis.workoutsオブジェクトに存在するかどうかを確認します.日付が存在する場合は、その日付にトレーニングをプッシュします.日付が存在しない場合は、キーとして、その日付でのトレーニングを作成します.一旦それがデータを通して繰り返されるならば、それは私が作成したrender()機能に行きます.
以下はレンダリング関数です:
    render(){
   this.workoutContainer = document.getElementById('workout-container')
        const workoutString = Object.keys(this.workouts).map((date) => {
           return `<button type="button" class="collapsible">${date}</button><div id="all-workouts">
            ${this.workouts[date].map((work) => work.renderHTML()).join(' ')}</div>`
        }).join(' ')
        this.workoutContainer.innerHTML = `${workoutString}`
    }
ドキュメントを使用してページ上にうまくレンダリングできました.HTMLの要素/divを選択するには、GetElementById (' workout -コンテナ')を返します.その後、this.workoutsオブジェクトのfetchメソッドを使用して、データを日付順にマップし、ボタンの日付を返しました.それから、私は日付でトレーニングを写像して、彼らをdivに置きました、そして、トレーニングは正常に各々のユーザーのために正しい日付の下でページに提出されました.
このコードはとても挑戦的でしたが、完成したときはとても嬉しかったです.私のプロジェクトを見て自由に、私はすべてのフィードバックと貢献を歓迎します.
いつものように、読書のおかげで!
心から
ブリタニー
今日の歌