学習の書き留め プログラミング勉強中

プログラミングで学んだことを日記として残して行こうと思います

今日の学習

今日学んだこと 2021/02/04

学習項目

devise応用

学習内容

エンジニアの方から、色々教えていただいたので、学習の書き留めとして残したいと思います。
実装内容
userとadmin(管理者)のdevise管理
個別のルーティング
個別のコントローラ(継承)
個別ページ
になります

devise導入

まずはアプリを作るところから
お好みだと思いますが、とりあえずバージョン6.0.0のmysqlで作ります。

rails _6.0.0_ new test_devise -d mysql

その後に、データベースの文字コードを少し変更
config/database.yml

default: &default
  adapter: mysql2
  # encoding: utf8mb4
  encoding: utf8 #ここをutf8に変える
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock

からのデータベース作成

cd test_devise
rails db:create

今回はdeviseのトレーニングですので、deviseをインストールします。
順番としては
1 Gemファイルにdeviseを記述
2 bundle install 3 rails g devise:install

# Gemfile
gem 'devise'

#コンソール
bundele install
rails g devise:install

rails g devise:installをすると

Depending on your application's configuration some manual setup may be required:
......

と言った記述があると思います。
設定方法について説明してくれているのですが、今回は3の

3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

に従います。
これは何なのかと言うと、viewsのアプリケーションファイルにpの記述をすると、ログインした後とかに、
ログイン成功しましたとかを書いてくれます。優秀!!!

と言うわけで、
app/views/layouts/application.html.erb.

<!DOCTYPE html>
<html>
  <head>
    <title>TestDevise2</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <p class="notice"><%= notice %></p> #今回はとりあえず、yieldの上にしました。
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>

これでオッケーです。

deviseを本格的に動かしたいところですが、その前にホームページを簡単に作ります。

#config/routes.rb
Rails.application.routes.draw do
  root to: 'hello#index'
end

#app/controllers/hello_controller.rb
class HelloController < ApplicationController
end

#app/views/hello/index.html.erb
hello world

まあ手書きしましたが、rails g controller hello index
でもどちらでも大丈夫です。

devise操作

ではここから本格的にdeviseを使っていきたいと思います。
まずは、user,adminの両方のmodel, controller, viewを作ります。
その後にマイグレートを行ってください。

#model
rails g devise user
rails g devise admin

#controller
rails g devise:controllers users
rails g devise:controllers admins

#view
rails g devise:views users
rails g devise:views admins

rails db:migrate

これで、あらかたできたのですが、rails routesをみると

                    new_admin_session GET    /admins/sign_in(.:format)                                                                devise/sessions#new
                        admin_session POST   /admins/sign_in(.:format)                                                                devise/sessions#create
                destroy_admin_session DELETE /admins/sign_out(.:format)                                                               devise/sessions#destroy
                   new_admin_password GET    /admins/password/new(.:format)                                                           devise/passwords#new
                  edit_admin_password GET    /admins/password/edit(.:format)                                                          devise/passwords#edit
                       admin_password PATCH  /admins/password(.:format)                                                               devise/passwords#update
                                      PUT    /admins/password(.:format)                                                               devise/passwords#update
                                      POST   /admins/password(.:format)                                                               devise/passwords#create
            cancel_admin_registration GET    /admins/cancel(.:format)                                                                 devise/registrations#cancel
               new_admin_registration GET    /admins/sign_up(.:format)                                                                devise/registrations#new
              edit_admin_registration GET    /admins/edit(.:format)                                                                   devise/registrations#edit
                   admin_registration PATCH  /admins(.:format)                                                                        devise/registrations#update
                                      PUT    /admins(.:format)                                                                        devise/registrations#update
                                      DELETE /admins(.:format)                                                                        devise/registrations#destroy
                                      POST   /admins(.:format)                                                                        devise/registrations#create
                     new_user_session GET    /users/sign_in(.:format)                                                                 devise/sessions#new
                         user_session POST   /users/sign_in(.:format)                                                                 devise/sessions#create
                 destroy_user_session DELETE /users/sign_out(.:format)                                                                devise/sessions#destroy
                    new_user_password GET    /users/password/new(.:format)                                                            devise/passwords#new
                   edit_user_password GET    /users/password/edit(.:format)                                                           devise/passwords#edit
                        user_password PATCH  /users/password(.:format)                                                                devise/passwords#update
                                      PUT    /users/password(.:format)                                                                devise/passwords#update
                                      POST   /users/password(.:format)                                                                devise/passwords#create
             cancel_user_registration GET    /users/cancel(.:format)                                                                  devise/registrations#cancel
                new_user_registration GET    /users/sign_up(.:format)                                                                 devise/registrations#new
               edit_user_registration GET    /users/edit(.:format)                                                                    devise/registrations#edit
                    user_registration PATCH  /users(.:format)                                                                         devise/registrations#update
                                      PUT    /users(.:format)                                                                         devise/registrations#update
                                      DELETE /users(.:format)                                                                         devise/registrations#destroy
                                      POST   /users(.:format)                                                                         devise/registrations#create
                                 root GET    /                                                                                        hello#index

となっています。こうなってしまうとuserもadminも全てdeviseのコントローラを経由してしまい、別々で処理ができません。
ですのでroutesをいじります。

Rails.application.routes.draw do
  devise_for :admins, controllers: {
    sessions:      'admins/sessions',
    passwords:     'admins/passwords',
    registrations: 'admins/registrations'
  }
  devise_for :users, controllers: {
    sessions:      'users/sessions',
    passwords:     'users/passwords',
    registrations: 'users/registrations'
  }
  root to: 'hello#index'
end

ほんとはadminは登録できない方がいいので後で消します。
こうすると、routesは

                    new_admin_session GET    /admins/sign_in(.:format)                                                                admins/sessions#new
                        admin_session POST   /admins/sign_in(.:format)                                                                admins/sessions#create
                destroy_admin_session DELETE /admins/sign_out(.:format)                                                               admins/sessions#destroy
                   new_admin_password GET    /admins/password/new(.:format)                                                           admins/passwords#new
                  edit_admin_password GET    /admins/password/edit(.:format)                                                          admins/passwords#edit
                       admin_password PATCH  /admins/password(.:format)                                                               admins/passwords#update
                                      PUT    /admins/password(.:format)                                                               admins/passwords#update
                                      POST   /admins/password(.:format)                                                               admins/passwords#create
            cancel_admin_registration GET    /admins/cancel(.:format)                                                                 admins/registrations#cancel
               new_admin_registration GET    /admins/sign_up(.:format)                                                                admins/registrations#new
              edit_admin_registration GET    /admins/edit(.:format)                                                                   admins/registrations#edit
                   admin_registration PATCH  /admins(.:format)                                                                        admins/registrations#update
                                      PUT    /admins(.:format)                                                                        admins/registrations#update
                                      DELETE /admins(.:format)                                                                        admins/registrations#destroy
                                      POST   /admins(.:format)                                                                        admins/registrations#create
                     new_user_session GET    /users/sign_in(.:format)                                                                 users/sessions#new
                         user_session POST   /users/sign_in(.:format)                                                                 users/sessions#create
                 destroy_user_session DELETE /users/sign_out(.:format)                                                                users/sessions#destroy
                    new_user_password GET    /users/password/new(.:format)                                                            users/passwords#new
                   edit_user_password GET    /users/password/edit(.:format)                                                           users/passwords#edit
                        user_password PATCH  /users/password(.:format)                                                                users/passwords#update
                                      PUT    /users/password(.:format)                                                                users/passwords#update
                                      POST   /users/password(.:format)                                                                users/passwords#create
             cancel_user_registration GET    /users/cancel(.:format)                                                                  users/registrations#cancel
                new_user_registration GET    /users/sign_up(.:format)                                                                 users/registrations#new
               edit_user_registration GET    /users/edit(.:format)                                                                    users/registrations#edit
                    user_registration PATCH  /users(.:format)                                                                         users/registrations#update
                                      PUT    /users(.:format)                                                                         users/registrations#update
                                      DELETE /users(.:format)                                                                         users/registrations#destroy
                                      POST   /users(.:format)                                                                         users/registrations#create
                                 root GET    /                                                                                        hello#index

となるのでそれぞれに対応した動きをすることができます。

adminの登録を消す

管理者はおいそれと新規登録できない方がいいので消したいと思います。
とりあえず挙動確認は必要なので、/admins/sign_upから1名だけ登録してください。
その後に、#app/models/admin.rbから

class Admin < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable, #←こいつを消す
         :recoverable, :rememberable, :validatable
end

registerableは新規登録に関わるものですので、消すないしはコメントアウトすることで、
以後urlを消すことができます。
そのほか、routesやviewファイルは消してしまって大丈夫です。

これで、例えば、userのログイン後に行き先をroot以外にしたい場合は

#app/controllers/users/sessions_controller.rb

protected #最後に記述する

  def after_sign_in_path_for(resource)
    #ログイン後移動させたい場所のパス
  end

で実装することができます。

ホームページを整える

現在、どっちのログインをしているかがわからないので、まず整えようと思います。

<% if user_signed_in? %>
<p><%= link_to"user:#{current_user.email} ログアウト", destroy_user_session_path, method: :delete %></p>
<% elsif admin_signed_in? %>
<p><%= link_to"admin:#{current_admin.email} ログアウト", destroy_admin_session_path, method: :delete %></p>
<% else %>
<p>not_login</p>
<% end %>

<p><%= link_to 'adminログイン', new_admin_session_path %></p>
<p><%= link_to 'userログイン', new_user_session_path %></p>
<p><%= link_to 'user登録', new_user_registration_path %></p>

これで、ログインないし、新規登録もでき、現在のログイン者もわかるようになったと思います。

個別のルーティング

個別のルーティングですが、各々のサービスで、ユーザーはユーザーのページ、管理者は管理者のページがあると管理しやすいと思いますので、
それを作っていきます。 それぞれ、ダッシュボードに行くことを目標とします。

まず、routesを

Rails.application.routes.draw do
  devise_for :admins, controllers: {
    sessions:      'admins/sessions',
    passwords:     'admins/passwords'
  }
  devise_for :users, controllers: {
    sessions:      'users/sessions',
    passwords:     'users/passwords',
    registrations: 'users/registrations'
  }
  root to: 'hello#index'

  namespace :users do
    resource :dashboards, only: [:show]
  end
  
  namespace :admins do
    resource :dashboards, only: [:show]
  end
end

と編集し、namespaceごとに分けてあげます。
そうすると、

users_dashboards_path  GET    /users/dashboards(.:format)   users/dashboards#show
admins_dashboards_path  GET    /admins/dashboards(.:format)  admins/dashboards#show

この二つのroutesが追加されたはずです。
これに合わせてcontrollerを作っていきます。 今回はuserに合わせて作っていきます ファイルの作り方は、

app/controllers/users/dashboards_controller.rb

と、userにdashboards_controller.rb記述します。 また、今回それぞれの動きに合わせて、共通処理も書いていきたいので、一緒に

rails g controller users

でuserコントローラーも作っておきます。
ここから、dashboards_controller.rbの書き方ですが、
userを通ること示すために、

module Users

end

とまず書きます。
または

class Users::

を頭につけます。

その後に、userコントローラを継承するので、最終的に、

module Users
  class DashboardsController < UsersController
    def show
    end
  end
end

#または

  class Users::DashboardsController < UsersController
    def show
    end
  end

と言う書き方になります。ちなみにmoduleの方が一般的らしいです。 showページはapp/views/users/dashboards/show.html.erb
とdashboardsフォルダを作って、そこにshowファイルを作ります。

共通の処理を記述する

今回、ログインしていた場合、showファイルを見れるようにするとした場合、
showファイルに書くのもいいですが、今後実装するものが増えた時に新しいcontrollerに毎回書かないといけなくなります。 Userコントローラを作って継承したので、そこに書いて、一回で済むようにしましょう。

class UsersController < ApplicationController
  before_action :login_check

    private

    def login_check
      unless user_signed_in?
        flash[:alert] = "ログインしてください"
        redirect_to new_user_session_path
      end
    end
end

これで、controllerが今後増えても、継承していけば、実装しなくてすみます。 共通の処理でいうと、サービスクラスがありますが、
サービスクラスは一連の動作をまとめたものですので、継承との処理をまとめるのは毛色が違います。

個別ページ

最後にユーザーのダッシュボードに飛んだ場合、レイアウトを変えたかったとします。
その場合は、app/views/layouts/application.html.erbをコピーして、 app/views/layouts/users.html.erbにします。
例えばファイルの中身を

<!DOCTYPE html>
<html>
  <head>
    <title>TestDevise2</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <p>ここだよここuserの時は追加されるよ!</p>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>

とすると、userコントローラを通るもののビューページは全てこれが適用されます。
また、意図的に変えたいレイアウトがある場合、controllerで

layout "変えたいレイアウト名"

にすると、変更ができます。

まとめ

実際に応用をするとすごく難しいけど、楽しい!!
これを引き出しにできるようにする。

今日の学習

今日は復習 2020/01/24

新しく学んだことがなかったわけではないが、
記事に書くこともなかったので復習も兼ねて今日はテストについて軽く書きたいと思います

rubyのtest

rubyにはもともとmini-testと呼ばれるテストが使えるようになっていますが、とはいえテストといえばやはりRSpecでしょうか。 今日はrailsRSpecをしたことはあると思いますが、ruby単体での導入方法を紹介したいと思います。
まあみなさんご存知だと思いますが。。。

とりあえず、ディレクトリは

Fizz_buzz  
  |-Irb fizz_buzz.rb  
  |-Test   

とします。 fizz_buzz.rbのテストで作る予定なので中身は、

def fizz_buzz(n)
  if n % 3 == 0 && n % 5 == 0
    "Fizz Buzz"
  elsif n % 3 == 0
    "Fizz"
  elsif n % 5 == 0
    "Buzz"
  else
    n.to_s
  end
end

puts fizz_buzz(1)
puts fizz_buzz(2)
puts fizz_buzz(3)
puts fizz_buzz(4)
puts fizz_buzz(5)
puts fizz_buzz(6)
puts fizz_buzz(15)

とします。

ここから導入方法です。

まずtestに移動

% cd test

Gemfileを生成

% bundle init

Gemfileにrspecのgemを記述

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem "rspec", ">= 3.0.0"

インストール

% bunlde install

ファイルの生成

% bundle exec rspec --init

ディレクトリの内容を確認します。

Fizz_Buzz  
  |- Irb  
  |- Test  
        |-Gemfile  
        |-Gemfile.lock  
        |-.spec  
        |-spec  
            |-spec_helper.rb  

となっていると思います。

spec_helper.rbの編集
=begin と =end の部分を削除してコメントを外す。(なぜこれをするのかまだわかってないです。)( ; ; )

あとは、テストファイルを作って内容を記述するだけです。

Fizz_Buzz
  |- Irb
  |- Test
        |-Gemfile
        |-Gemfile.lock
        |-.spec
        |-spec
            |-fizz_buzz_test.rb
            |-spec_helper.rb
require '../../Irb/fizz_buzz.rb'

RSpec.describe 'Fizz Buzz' do
  example 'fizz_buzz' do
    expect(fizz_buzz(1)).to eq '1'
    expect(fizz_buzz(2)).to eq '2'
    expect(fizz_buzz(3)).to eq 'Fizz'
    expect(fizz_buzz(4)).to eq '4'
    expect(fizz_buzz(5)).to eq 'Buzz'
    expect(fizz_buzz(6)).to eq 'Fizz'
    expect(fizz_buzz(15)).to eq 'Fizz Buzz'
  end
end

まとめ

まだあいまいのところもあるからゆっくり理解していく。

今日の学習

今日学んだこと 2021/01/23

学習項目

ajax

学習内容

ajaxとは非同期通信のことで、ページを更新せずに情報を更新する仕組みのことを言う。
通常の方法とは異なり、jsを使い行う。
jsを使うことで、そのままコントローラーに連絡ができ、他のページを更新する必要がなくなる。
主なサービスとしてはマップの埋め込みや、メッセージアプリなどがある。

ルーティングの設定としてはデータ返却のアクションを実行するためのURLとしてエンドポイントを設定する。簡単に言うとjson用のルーティング的なもだと思う。

例えばクリックしたら、既読にする等のアクションでは
まず、クリックしたら、アクションを動くようする。(イベントハンドラーと言う)
クリックしたあとはエンドポイントにリクエストを送る記述をする。(XMLHttpRequestと言うオブジェクトを使う。)
クリックしたものがどれかを判別するためにビューファイルにカスタムデータを記述(data-<情報>で記述)
リクエスト内容はXHR.open(HTTPメソッド, パス, 非同期かどうか)で記述
レスポンスの内容は何がいいのかをXHR.responseTypeで記述(例:XHR.responseType = "json";)
最後にXHR.sendを記述して、送信する。

function check () {
  const kidokus = document.querySelectorAll("既読をつけたい要素");
  kidokus.forEach(function(kidoku) {
    kidoku.addEventListener("click", () => {
      const kidokuId = kidoku.getAttribute("data-id");
      const XHR = new XHRHttpRequest();
      XHR.open("GET", `/kidokus/${kidokuId}`, true);
      XHR.requestType = "json";
      XHR.send();
    });
  });
}
window.addEventListener("load", check)

と言う感じになる。ここまでが、リクエストを送る内容。
レスポンスが返ってきたあとは、onloadを使用し、その後に記述する。
大体流れはこんな感じ。

まとめ

ほんとはどう言うことをしていくのかを書きたいが、内容が複雑のため、ゆっくり勉強する。
今日は今回のように流れがわかったのでよし。

今日の学習

今日学んだこと 2021/01/19

学習項目

Java Script 基礎 2

学習内容

機能の学習に続いて、取得した要素をどう動かしていくかを学んだ。

インラインスタイル

HTML要素の開始タグの中に直接CSSソースコードを記述するプロパティの指定方法。
インラインスタイルの追加と削除はそれぞれsetAttributeとremoveAttributeというメソッドを使用する。

setAttributeメソッド

指定した要素上に新しい属性を追加、または既存の属性の値を変更できる。

要素.setAttribute(name, value)

// nameは属性の名前を文字列で指定
// valueは属性に設定したい値を指定

removeAttributeメソッド

指定した要素から、特定の属性を削除する。

要素.removeAttribute(name, value)

// nameは属性の名前を文字列で指定
// valueは属性に設定したい値を指定

この二つを用いることで、例えば

<span id="change-hover">test</span>
#sample {color: red;}

といった文字がサイトに表示あったとして、

function changeColor() {
// IDを取得
const changeHoverColor = document.getElementById("change-hover")

// マウスを当てたときに色を変えるようにする
// 1.当てたときにイベント発火
changeHoverColor.addEventListener('mouseover, function(){
// 2.色を変える
  this.setAttribute("style", "color:blue;")
})

// マウスを離した時に色を元に戻すようにする(変更を消す)
// 1.離した時にイベント発火
changeColor.addEventListener('mouseout', function(){
// 2.色を戻す
  this.removeAttribute("style", "color:blue;")
})
window.addEventListener('load', change)  

というように記述することで、マウスを当てると赤→青、マウスを話すと青→赤
と変化する。
またthisを利用することで、イベントの発火元となった要素を取得することができるため、記述を少なくすることができる。

getAttributeメソッド

要素上の指定した属性の値を戻り値として返すメソッド。

要素.getAttribute('属性名')

このメソッドを使うことで、クリックをしたことで、変更する等の使用を実装できる。

<span id="change-click">クリックすると色が変わる</span>
#change-click {color: red;}
function changeColor() {
  // IDを取得
  const changeClickColor = document.getElementById("change-click")
  // クリックした時に色を変えるようにする
  // 1.クリックした時にイベント発火
  changeClickColor.addEventListener('click', function() {
  // 2.今の属性を取得し、if文で状況に応じて色を変える
    if (changeClickColor.getAttribute("style") == "color:blue;") {
      this.removeAttribute("style", "color:blue;")
    } else {
      this.setAttribute("style", "color:blue;")
    }
  })
}

window.addEventListener('load', changeColor)   

これで、cssが青の時は青色を取り除く(赤色にする)にし、そのほかの色の時は青色を付与するという実装ができる。

debugger

debuggerを用いることで、ソースコードに処理を一旦停止させる場所を指定することができる。処理が停止している状態で、特定の変数の値を確認したり、1行だけ処理を進めたりなど、幅広いデバッグが可能となる。

innerHTML

innerHTMLを使用すると、HTML要素の取得や書き換えを行うことができる。

<span id="change-html">選択すると文字が変わる</span>
  <ul>
    <li class="choice-class">1: 選択肢</li>
    <li class="choice-class">2: 選択肢</li>
    <li class="choice-class">3: 選択肢</li>
    <li class="choice-class">4: 選択肢</li>
  </ul>
function changeColor() {
// IDを取得
  const ChangeHtml = document.getElementById("change-html")
  const choiceClickHtml = document.querySelectorAll(".choice-class")

  // forEach文を使って、choice-classの全てが同じ処理をできるようにする
  choiceClickHtml.forEach(function(choice){
    // クリックした時にイベント発火
    choice.addEventListener('click', function() {
      // choice-classの文字列を取得し変数に代入
      value = choice.innerHTML
      // change-htmlの文字列に先程の変数を代入することで、文字を変える
      ChangeHtml.innerHTML = value
    })
  })
}
window.addEventListener('load', changeColor)   

HTML情報を取得し、ほかに代入することで文字を変えることができる。

また、昨日の記事では先頭にwindow.addEventListener('load', function(){}を記述していたが、一般的ではないらしく、 function 関数名(){} を記述して、関数を定義して、その中に記述し、その後に
window.addEventListener('load', 関数名)を記述して、関数を読み込むというのが一般的。

まとめ

なんとなく、文法、動かし方がわかってきたと思う。でもこういうのって、多分発想が重要になってくるから、ほかのコードを見たりすることも同じぐらい大事だと思った。

今日の学習

今日学んだこと 2021/01/18

学習項目

Java Script 基礎

学習内容

まず、script src でjsのファイルを読み込む。

<head>
  <link rel="stylesheet" href="index.css">
  <script src="index.js"></script>
  <meta charset="UTF-8">
  <title>JavaScriptの練習サイト</title>
</head>

jsではHTMLに対して行う処理の要求のことをイベントという。
また、イベントを認識して、コードが動き出すことをイベント発火という。

主なイベント発火の例

イベント名 説明
loadイベント ページ全体が全て読み込まれた後に、イベント発火する
clickイベント 指定された要素がクリックされた時に、イベントが発火する
mouseoverイベント マウスカーソルが指定された要素上に乗った時に、イベントが発火する
mouseoutイベント マウスカーソルが指定された要素上から外れた時に、イベントが発火する

イベントの発火方法

要素.addEventListener(`イベント名`, 関数)

記入例

window.addEventListener('load', function(){
  const sample = document.getElementById("sample")
  sample.addEventListener('mouseover', function(){
    console.log("カーソルを当てた際のイベント")
  })
})

こんな感じになる。まず、javascriptのコードはbody要素より先に読み込まれる。
そのため、最初に window.addEventListener('load', function(){})の関数の中に記載し、ロードをした後に全てのイベントが発火するようにする。
その後constで何を動かしたいのかを定義する。その際にdocument.getElementById()を使って、どのIDかを指定し、その要素を取得する。 あとは、取得した要素をどう動かすのかをそれぞれのイベントに合わせて記載する。
このコードはページが表示された際に、HTMLのsampleIDを取得し、マウスが当たった際にイベントを行うように記載してます。

まとめ

まずはどう動かせばいいのかをつかむ!

今日の学習

今日学んだこと 2021/01/17

学習項目

Java Script 概要

学習内容

Java Scriptとはプログラミング言語の一つでクライアントサイドで力を発揮する。
サイトに動きをつけることができ、例えば
ページ遷移なしで画面表示を切り替えられる
画面更新をせずにサーバーと通信ができる
などのメリットがあり、使い勝手の良いWebページを作成できる。

デベロッパツール

開発者ツール、検証ツールと呼ばれる。HTMLやCSSの確認・編集はElements(エレメンツ)パネル、JavaScriptの実行はConsole(コンソール)パネルにて行うことができる。
console.log: ブラウザのコンソールにテキストを表示させるメソッド。

変数、定数定義

var: 再定義、再代入可能、古い書き方
const: 再定義、再代入不可
let: 再定義不可、再代入可能

var sample = "test"
const sample = "test"
let sample = "test"

テンプレートリテラル

テンプレートリテラルは``で囲むことで使用でき、${}のなかに記入する。

let sample = "test"
console.log(`これは${sample}です`)
// => これはテストです

条件分岐

if文の書き方

if (条件式1) {
  // 条件式1がtrueの時の処理
} else if (条件式2) {
  // 条件式2がtrueの時の処理
} else {
  // どちらもfalseの時の処理
}

配列の取得

rubyの変わらない

繰り返し処理

for文

for (初期化式; 条件式; 加算式) {
  // 繰り返す処理の内容
}

// 例
for (let i = 0; i < 10; i++) {
  console.log(i)
}
// 0~9を表示する

forEach関数
rubyのeachと似たようなやつ

配列.forEach( function(value) {
  // 処理の記述
})

関数定義

rubyでいうところのメソッドをjavascriptでは関数と呼ぶ。まぁ微妙に違うらしいが。
定義方法

function 関数名(仮引数) {
  // 処理
}
console.log(実引数)

また、javascriptでは戻り値をreturnを用いて明示する必要がある。

function calc(num1,num2){
  return num1*num2
}

const num1 = 3
const num2 = 4
console.log(calc(num1,num2))

関数宣言と関数式

見た方が早い

// 関数宣言
function 関数名( 引数 ){
  // 関数内の処理
}

// 関数式
変数 = function( 引数 ){
  // 関数内の処理
}

補足として、javascriptでは関数宣言が先に読み込まれるという性質がある

無名関数と即時関数

無名関数とはその名の通り関数名無しで定義すること。関数を多く使用するコードであるときに使用する。関数名の重複を避けることができる。

即時関数とは関数を定義すると同時に実行される構文のこと。流用する可能性のない関数を定義するときに使用する。別途関数を定義する手間がない。

// 無名関数
const sample = function(num) {
  console.log(num)
}
countNum(1)

// 即時関数
(function sample(num) {
  console.log(num)
})(1)

アロー関数

まぁざっくりいうと省略形のことです。無名関数または即時関数において、より省略した記述をしたい時に使用する。

const 変数名 = (引数) => {
  処理
}

javascriptにおけるオブジェクト

JavaScriptにおけるオブジェクトとは、データや処理といった情報を1つにまとめた集合体のこと。
データはキーとバリューのセットとなったプロパティを指し、突き詰めると、オブジェクトはプロパティの集合体から成り立っている。

JavaScriptにおけるメソッド

JavaScriptおけるメソッドとは、プロパティに紐づけられた処理のこと指し、関数を用いることで代入できる。

let sample {
  name: "sample",
  test: fuction(){...},
}

sample.test()

もともとあるオブジェクト

windowオブジェクト
ブラウザの情報を持っているオブジェクト
documentオブジェクト
ブラウザ上で表示された情報(HTML)を操作する事ができるオブジェクト

DOM

Document Object Model(ドキュメントオブジェクトモデル)の略。HTMLを解析し、データを作成する仕組み。
ざっくりいうとHTMLの要素をJavaScript上で取得し操作するための仕組み

HTML情報を取得する方法

document.getElementById("id名")
引数に渡したidを持つ要素を取得。
document.getElementsByClassName("class名")
classを指定して取得する。getElementsは複数形。
document.querySelectorAll("セレクタ名")
セレクタ名を指定して取得する。
document.querySelector("セレクタ名")
HTML上から引数で指定したセレクタに合致する要素のうち一番最初に見つかった要素1つを取得する。

まとめ

似てるところも多いけど、フロントよりの言語ということもあって、混乱する。
ゆっくり整理する。
ただ、他の言語を学ぶことで、オブジェクトとは何なのか、returnをどう使うのかとか、より内側を知ることができた気がする。

今日の学習

今日学んだこと 2021/01/16

学習項目

MVC応用

学習内容

View

railsのコントローラーでの処理後、レスポンスでHTMLが表示されるのはAction Viewという仕組みを搭載しているから。
Action Viewとは、ざっくりいうとビューの機能がまとまっているもの
これによってビューファイルが見れるようになっている。
注意としては、ビューファイルがそのまま表示されているわけではなく、ビューファイルの内容がAction Viewにまとめられてブラウザに返却されているということ。
また、コントローラーで取得したインスタンス変数はビューファイルでそのまま使えているように見えているが、実際は裏側で色々と複数のメソッドを経て読み替えられた後、再度同じインスタンス変数としてセットされて使用している。

ヘルパーメソッドについて

ヘルパーメソッドの仕組み自体はざっくりいうと、例えば、<%= link_to %>で書いた場合、< a hlef >となるように処理されている。
んで、このヘルパーメソッドは自作が可能。 Helperというヘルパーメソッドを作成できるモジュール(インスタンスを生成できないクラス、主にメソッドようかな、多分)が app/helpers に用意されている。 そこに def メソッド名 ~ end で定義するとビューファイルで、<%= メソッド名 %>で使用することができる。

Controller

railsのコントローラーがコントローラーの機能を果たすのはコントローラーの機能ではなく正確にはAction Controller という機能を搭載しているため。なんか説明がよくわからんけど、、、笑 コントローラーの役割はリクエストを受け取り、レスポンスをかえすことであるため、細かい処理はモデルに記述するのが好ましい。
そうすることで、可読性を上げることができる。

サービスクラス

また、モデルに記述する際に処理が複雑になる場合、モデルの記述が複雑になる。そういった場合はサービスクラスに切り出すのが好ましい。 app/servicesを作成し、内容のわかるファイル名を作成する。

# app/services/sample.rb

class Sample
  def self.sample(text)
    # 切り出したい処理
  end
end

# app/controllers/sample_controller.rb

class SampleController < ApplicationController
  def sample
    @sample = Sample.sample(params[:text])
  end
end

セッションとクッキーについて

自動ログインだったり、一時的に自分の情報が保存されている経験があると思う。
これはセッションとクッキーの二つで成り立っている。

セッション

Webサービスにおいて情報を一時的に記憶しておく仕組みのこと。
rails では ssession[:sample] と記述することで行うことができる。

クッキー

焼くやつじゃないです。お菓子でもないです。じゃあなにそれ美味しいの?と言われても食べ物じゃないです(笑)
最近のサイトだとクッキーを使用していいですかとか聞かれるんじゃないかな?多分あれのこと。
クッキーとはブラウザが持っているデータが保存できる領域のこと。
ブラウザにあるセッションの情報の保存場所のことをクッキーと呼ぶ。
rails ではデフォルトでCookieStoreに保存されている。

セッションとクッキーの違いについて

なにが違うのかというと、セッションはあくまで仕組み、技術をさしている。ユーザー情報をを一時的に保存するまでのやりとり。
クッキーは場所を指しているということ。一時的に情報を保存している場所のこと。

Model

rails ではモデルの機能を実現するためにActive Modelを搭載している。
また、モデルによるデータベースの操作はActive Recordによって実現しているが、この技術はORMという技術に分類される。ActiveRecord自体はテーブル操作する際に使うプログラムをまとめたもののことを指す。

ORM

RDBのデータを、オブジェクト指向プログラミング言語でオブジェクトとして使用するために変換する技術

RDBSQL

Relational Database(リレーショナルデータベース)の略語。
関係データベースと訳され、データを複数の表として管理し、表と表の関係を定義することで、複雑なデータの関連性を扱えるようにしたデータベース管理方式。
今回では、フツーにデータベースと思って良いと思われ。
実際にRDB、データベースを操作しているのはSQLと呼ばれる言語。
つまり、ActiveRecordなどのORMのメソッドは、SQLに変換されるためテーブルの操作が可能になる。

SQLの命令には大きく3つに分類されており、
データを定義するDDL(Data Definition Language)
→DBやテーブルを作成、削除
データを操作するDML(Data Manipulation Language)
→データを探す、登録する、更新する
データを制御するDCL(Data Control Language)
→変更を確定する、取り消す
になる。

まとめ

かなりrailsのコアの部分について学習したと思う。ここにげない。railsに振り回されるのではなく、今後も付き合っていくためにゆっくり自分に落とし込んでいく。