tawara's blog

雑記。個人の見解です。

git commit --allow-empty で空コミットを作成してPR作るといい感じ

こんにちは、たわらです。

つよつよエンジニアに教えてもらった、プルリクの作り方のメモを残しておきます。

  • developブランチをpullして最新の状態にする
  • git flow feature start チケット名_簡単な名前 * git flow を使用している場合
  • git commit --allow-empty で空コミットを作成する
  • git push する
  • ファイル差分のないPRの概要のところにチケットのURLと詳細説明と実装Todoチェックリストを作成する
  • いざ開発を進める (できるだけ細かい粒度のcommitを心がける)

実際これにのっとって開発を進めましたが、とても効率よく進めている感じがします。

先に段取りを決めておけるのがいい感じです。

こういう効率のよい開発のTips? は職場でないと学べないのかなと思います。教えてもらってとても感謝です。

たわら

パRailsの第2章のメモ

  • Model
    • データベースとの接続とデータに対する操作、ビジネスロックを担当する
  • View
    • Model の内包を参照して、視覚表現を行う部分
  • Controller
    • Modelのロジックを呼び出し、必要なViewの選択したり、ModelとViewをつなぐ部分

モデル

  • ActiveRecordによるモデルには大きく2つ役割がある
    • データベースと接続してデータベースのレコードとActiveRecordオブジェクトを結びつける
    • よりビジネスロジックの実装的なふるまいをすること。バリデーションやレコード保存時などに実行するさまざまなコールバックなどを実行する
  • CRUDとはデータベースのレコードに対する基本的な操作のことを言う。Create、Read、Update、Delete。作る、参照する、更新する、削除する。
  • ActiveRecordクラスがバリデーションに失敗すると、どのフィールドでどのようのなエラーが発生したかをインスタンス変数に記録する
  • 保存操作を行うcreateやupdateのメソッドには、create!、update!などの!を伴うメソッドがある。
    • ! をつけるとバリデーション失敗時に例外「ActiveRecord::RecordInvalid」が起きる
    • つけないと例外は起きない。true/false で分岐処理するときなんかはこちらを使用する
  • レコードを作成して保存する一連の流れの間のさまざまな箇所で任意の処理を呼べる。特定の処理に引っ掛けて別の処理を呼ぶことをコールバックという

  • ActiveRecordが提供するenum型は数値のカラムに対してプログラム上で扱える別名を与えることができる

コントローラー

  • アクションの前後に処理を差し込むコールバック処理のようなものをフックと呼ぶ。

    ```s before_action :set_book, only: [:show, :destroy]

    def set_book @book = Book.find(params[:id]) end ```

    みたいなやつ。only や exceptオプションでアクションを制限することができる。

  • RailsにおけるCSRFcross-site request forgeries クロスサイトリクエストフォジェリー)とは

    • 悪意ある第三者が用意したリンクなどをサービス利用者が踏んだときに、ユーザーの意図に反してデータの削除などが行われてしまう問題
    • 対策としてRailsはデータの削除などを利用する場合、リクエストに対してあらかじめセキュリティトークンを発行している。リクエスト時に発信されたトークンを検証することで第三者ではなくユーザーのリクエストであることを判定している。
    • トークンで正しいリクエストかどうかを判断しているということらしい
  • resourcesのブロック内にmemberを利用すると「/publishers/:id/detail」のように個別のリソースに対してアクションを設定する。collectionを利用すると「/publishers/search」のように、全体のリソースに対してアクションを設定できる。

    • リソースに対してアクションを設定するという言葉遣いをするみたい。なるほど。
  • 例外処理
  • ユーザーに通知すべき例外処理などは基本的にコントローラが担当する。いくつかの特定クラスに対応するステータスコードRailsは用意している。特定の例外に特定のレスポンスを返したい場合は、rescure_fromを使う。例外クラスを指定し、withオプションで例外発生時に呼ばれるアクションを指定する
  • StrongParametersはMassAssignment機能を利用する際の脆弱性に対抗するためのもの。MassAssignmentとは、Rubyのハッシュを使って、モデルの属性の生成・更新を一括で設定する機能のこと。
    • 危険性とは、意図しない属性の変更を一般ユーザーに許してしまうことを指す。リクエストにキーを指定し、そのなかの特定のキーのみ受け付ける、という制限をかけることができる。

ビュー

  • ビューはコントローラーで取得したデータをユーザーが認識可能な形式にレンダリングするところ。HTMLでの表示やAPIでの返り値だったりする。
  • respond_to ブロックを使うと、htmlやjsonフォーマットを出し分けることができる
  • variants を使用すると条件によってテンプレートを切り替えることができる
  • Railsでは、開発の手助けとなるビューヘルパーを用意してくれている。例えばform_with。
  • Prifixの値+ pathを付けるとドメインやポート番号を除いた/から始まるパスの部分を返し、+ urlだとドメインなどを含めた完全なパスを返す
  • HTMLのビューを動的に生成する場合、セキュリティからの観点で気をつけるべきは、クロスサイトスクリプティング。プログラムが意図しない文字列を渡すことで、あるページに対して自由にJavascriptを埋め込んで、実行させてしまう攻撃方法のこと。
  • Stringのオブジェクトをテンプレートエンジン内で描画しようとすると、自的動にHTMLタグに対してエスケープ処理を施すことでクロスサイトスクリプティングに対策している。
  • APIサーバーにとってのビューの役割はJsonを生成すること。Railsでは組み込みで jbuilderというgemパッケージを利用していて、jbuilderを使うことで宣言的にJSONデータを整形できる。

まとめ

  • アプリケーションの主要なロジックはなるべくモデルに書くこと

パRailsの読書メモ 第1章

こんにちは、たわらです。

パーフェクトRuby on Rails【増補改訂版】の読書メモです。

  • Rubyをインストールするとgemコマンドが使えるようになる

    • Gemコマンドを使うとRubyで出来ている配布用ライブラリのgemを管理できる。
  • Rubyをインストールするとrakeコマンドが使えるようになる

    • rakeコマンドはタスクランナーで、実行する処理をRakeタスクと呼ぶ。
    • 主にリリース作業などの定形処理を実行する(基礎課題では記事更新のRakeタスクを作ったな)
  • Rubyをインストールするとbundleコマンドが使えるようになる

    • 「開発しているプロジェクト内でどのgemを使用しているか」「どのバージョンを使用しているか」を明示する仕組み
    • Gemfileという設定ファイルにgemパッケージ名を書く。gemのバージョンや依存関係を解決した結果をGemfile.lockに保存する。Gemfile.lockがある場合、bundle installはこれを参照する。プロジェクトに新しく参加する人もこれを参照することで同じバージョンのgemを利用できる。
  • Gemfile

    • git_source はgemパッケージを検索するサーバーの設定
  • bundle exec コマンド Bundlerでインストールされているgemを使用してコマンドを実行する

  • Railsの思想

    • 設定より規約
      • 規約に従うことで設定ファイルを減らし、コミュニケーションがスムーズになり、本来注力すべきビジネスロジックに集中できる
    • DRY
      • 同じことを繰り返さない
    • REST
      • /employees/1 URIが示す内容を「リソース」と呼ぶ。社員情報を取得する処理は/employees/1へHTTPのGETメソッドでアクセスして取得する
    • 自動テスト
  • 主要なファイルやディレクト

    • bin/ アプリケーションを開発するために利用する実行コマンドを格納しているディレクト
    • lib/ Rakeタスクなどアプリケーションから独立したコードを格納するディレクト
    • config/ アプリケーションの動作に関する設定ファイルを格納するディレクト
    • bundle exec をつけなくても実行できるコマンドをbinディレクトリに用意している。このファイルをbinstubという
  • DSLとはドメイン特化言語ドメインとっかげんご domain-specific language、DSL)とは、特定のタスク向けに設計されたコンピュータ言語

  • db:migrateってrakeコマンド

  • (.:format)はアクセスしたURLによってレスポンスを変化させるために使う。

聞いたことあるAWSのサービスをざっくり調べてみた

こんにちは、たわらです。

HerokuとAWSの違いがよくわからないし、EC2って聞いたことあるけどよく知らないので、ざっくり調べてみました。

Heroku

  • アプリケーションの開発から実行、運用までをクラウド上で管理できるPaaS(サービスとしてのプラットフォーム)
  • PaaSとは、インターネット上でハードウェアやOSなどを提供するサービス。低コストかつ迅速な開発がメリット。
  • JavaからGoまで、もちろんRubyも公式サポートしている
  • スマートコンテナ「dyno」がアプリの調整や管理をしてくれる
  • 構築が簡単
  • Network/Hard Ware/OS/Middle Ware までを提供するクラウドサービス。Applicationはユーザーが用意。

AWS

  • 主要な言語のサポート
  • 使用方法に応じて料金体系が変わる
  • laaS。サービスとしてのインストラクチャー。
  • Network/Hard Ware/OS までを提供するクラウドサービス。Middle WareとApplicationはユーザーが用意。

これによくまとまってる。ちと読みづらいけど。 qastack.jp

Herokuはアプリだけ作ればデプロイできるけど、AWSを利用する場合は自分でEC2(?)などアプリを載せる層をカスタマイズ/選択をする。 だからユーザーがより現実に対応した環境を整えられる、という感じですね。

AWSの用語

Railsをデプロイするのに、AWSのEC2インスタンス環境構築?をする必要がある。 構築に必要なのは「web3層構成」。

  • webサーバー層

    webブラウザからのアクセス要求を処理。必要に応じてWebアプリケーション層へリクエスト要求する

  • webアプリケーション層

    webサーバーからのリクエストをもとに、バックエンドのRubyなどを実行したり、データベースへアクセス。

  • データベース層

    データの保持。 これらをEC2インスタンスのなかに構築する。

VPCの作成

  • Virtual Praibate Cloud。自分専用の領域。サブネットやEC2などはこの領域の中に作成する。

サブネットの作成

  • ネットワークのなかのネットワーク

  • このサブネットは外部との通信をする(パブリックサブネット)/VPC内だけの通信にする(プライベートサブネット) などの制御するため

  • Railsを置くEC2はパブリックサブネット、RDS(Relational Database Service)はEC2からのアクセスのみなのでプライベートサブネット。

アベリラビリティゾーンとは?

  • サーバーを物理的に置いているデータセンターについて、各リージョンで地域ごとにデータセンターを分けた集合の単位。

  • RDSでは異なるAZを持つ複数のサブネットを設定したサブネットグループを登録する。1つがサーバーダウンしても大丈夫にするため。

インターネットゲートウェイを作成する

  • VPCAWS内での専有領域なので、外部と接続をするには、窓口が必要。

ルートテーブルを作成する

  • 通信に関するルールブックのような概念。サブネット単位で設定が可能。IPアドレスによって通信の経路を変える。パブリックサブネットには宛先が振当てられない。

セキュリティグループを作成する

  • セキュリティのルールを設定する。適応されたグループごとに通信の許可/拒否ができる。各サブネットを囲うファイアウォール

EC2とは?

  • Amazon Elastic Compute Cloud。仮想サーバー。仮想サーバーの実態をEC2インスタンスという単位で構築する。

  • webサーバー層  webブラウザからのアクセス要求を処理。必要に応じてWebアプリケーション層へリクエスト要求する →ミドルウェア : Nginx を使用するサーバー

  • webアプリケーション層  webサーバーからのリクエストをもとに、バックエンドのRubyなどを実行したり、データベースへアクセス。 →ミドルウェア : Puma を使用するサーバー

  • データベース層  データの保持。 →ミドルウェア : MySQL を使用するサーバー

Nginxとは?

  • 大量のアクセス処理に特化したwebサーバー
  • Pumaのみでもアプリケーションは動かせるが、ローカルの場合アクセスが自分ひとりだから
  • Apacheの改善により開発
  • EC2にインストールして起動する

Elastic IPアドレス (EIP)とは

Capistranoとは?

  • デプロイ先のEC2インスタンスSSH接続して指定されたコマンドを実行してくれる。EC2にSSH接続するよりは手間がかからない。

Route 53 とは?

S3 とは?

  • Simple Storage Service。オブジェクトストレージサービス
  • 保存したぶんだけ課金。
  • S3の料金 = ストレージに保存している容量 + S3に対するリクエスト(GET、PUTなど)数 + データ転送料金
  • 柔軟なストレージ機能,耐久性と可用性の高さ,低コストによる運用が可能,静的ファイルの配信,豊富なツールや機能

ACMとは?

  • AWSが提供しているSSL証明書
  • SSL(Secure Sockets Layer)とは、インターネット上におけるウェブブラウザとウェブサーバ間でのデータの通信を暗号化し、送受信させる仕組みのことです。
  • 無料、ワイルドカード可、自動更新

超基本 CRUDで他人の投稿の編集・更新を防ぐコントローラーでの注意点

こんちには、たわらです。

ポートフォリオを作成していて、一段落したので講師のかたに簡単にコードを見てもらったのですが、超基本的なところの理解ができていなかったので、反省をこめてメモを残しておきます。

編集・更新は投稿した本人のみができるようでなければならないのです。current_userに紐付いている投稿群から検索するようにコードを書きます。 current_user.postsとするところがポイントです。

  # ユーザー全員がアクセスしてよい
  def show
    @post = Post.find(params[:id])
  end
  
  
  ########## Bad ##########
  # これだとposts/18/editの数字の部分を改ざんすれば他人の投稿を編集・更新できる
  def edit
    @post = Post.find(params[:id])
  end
  
  def update
    @post = Post.find(params[:id])
    # 必要な処理
  end

 ########## Good ##########
 # これだと現在のユーザーの投稿から検索するので他人の投稿へのアクセスを防げる
  def edit
    @post = current_user.posts.find(params[:id])
  end
  
  def update
    @post = current_user.posts.find(params[:id])
    # 必要な処理
  end

かつて学習した超基本が身についてないとショックを受けますが、恥はかきすて、と考えて素直に復習しようっと。

Rails6 にBootstrapとJQueryとMaterial design for bootstrap 4をwebpackerで導入したメモ

こんにちは、たわらです。

先日からポートフォリオの制作に着手しました。Rails newをしてとりあえずフロントまわりに必要なものを導入した際の手順をまとめる記事です。

先人の知恵を借りたけどできなかった

[Rails6.0] Rails6 + yarn + webpacker でMaterial Design for Bootstrapを導入する - Qiita

Rails6 Material Design for Bootstrapを使用する手順 | mebee

Rails6 で Material Design for Bootstrap を使う | url4u.jp

このあたりのブログを参考に導入をしてみた。

$ yarn add bootstrap bootstrap-material-design jquery popper.js

で、必要なファイルをインストールする。

下記のようにエントリーファイルを作成する。

# app/javascript/pack/application.js
import 'bootstrap-material-design'
import '../stylesheets/application'

cssを配置するディレクトリとファイルを作成する。

$ mkdir app/javascript/stylesheets
$ touch app/javascript/stylesheets/application.scss

作成したapplication.scssに以下のコードを追加する。

@import '~bootstrap-material-design/scss/bootstrap-material-design';

そしてレイアウトファイルでエントリーファイルを読み込むように下記のコードを記載。(turbolinksは使ってません)

= stylesheet_pack_tag 'application', media: 'all'
= javascript_pack_tag 'application'

Material design for bootstrap 4が利用できない

ここまでの手順ではどうしてかMaterial design for bootstrap 4が反映されていませんでした。ただのbootstrapです。特にエラーもありません。

なんでかなーと思って公式を確認すると、どうやらMaterial design for bootstrap 4のバージョンが違うようでした。

$ yarn add bootstrap bootstrap-material-design jquery popper.js

のやり方だとバージョン4.1.3になっていました。

しかし公式を見てみると、

npm install bootstrap-material-design@4.1.1

と書いてあります! 

https://fezvrasta.github.io/bootstrap-material-design/docs/4.0/getting-started/download/

なので、公式にならってインストールします。これでpackage.jsonにてバージョンが4.1.1に変更されます。

すると、下記のエラーがはじめて出てきました。とにかく進んでるっぽいですね。

ERROR in ./app/javascript/stylesheets/application.scss (./node_modules/css-loader/dist/cjs.js??ref--7-1!./node_modules/postcss-loader/src??ref--7-2!./node_modules/sass-loader/dist/cjs.js??ref--7-3!./app/javascript/stylesheets/application.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):    @include form-validation-state("valid", $label-color);
            ^
      Mixin form-validation-state is missing argument $icon.
      in /Users/kentaroutawara/programing/nisatume/nisatume/node_modules/bootstrap-material-design/scss/mixins/_forms.scss (line 159, column 14)
Error:
    @include form-validation-state("valid", $label-color);
            ^
      Mixin form-validation-state is missing argument $icon.
      in /Users/kentaroutawara/programing/nisatume/nisatume/node_modules/bootstrap-material-design/scss/mixins/_forms.scss (line 159, column 14)
    at options.error (/Users/kentaroutawara/programing/nisatume/nisatume/node_modules/node-sass/lib/index.js:291:26)

で、エラー箇所の

Mixin form-validation-state is missing argument $icon.

で試しにググってみると、別のrepoのissueに出会う。そのものズバリの内容でした。いいねがたくさんついてる解決法を実施するとうまくいきました!

github.com

node_modules/bootstrap-material-design/scss/mixins/_forms.scssの159行目を

@include form-validation-state("valid", $label-color);

から

@include form-validation-state("valid", $label-color, "none");

に変更します。

この変更による影響範囲は正直把握しきれませんが、これでMaterial design for bootstrap 4は反映されます。

反省

何はともあれ公式を読んでみることは大事です

参考文献

[Rails6.0] Rails6 + yarn + webpacker でMaterial Design for Bootstrapを導入する - Qiita

Rails6 Material Design for Bootstrapを使用する手順 | mebee

Rails6 で Material Design for Bootstrap を使う | url4u.jp

https://fezvrasta.github.io/bootstrap-material-design/docs/4.0/getting-started/download/

jQueryをざっくり勉強する

こんにちは、たわらです。

本記事はJQueryをざっくり理解するために必要な知識をまとめた記事です。

「要素を指定する」→「それに何かをする」

JQueryの基本的な考え方は、「何かを取ってくる」→「それに何かする」です。下記の参考書がわかりやすかったです。

この考え方を理解できればコードを見ても何がしたいのかがわかります。

$('#sample1').hide();

このコードは、「id属性がsample1である要素を隠す」ということです。

<div id = "sample1">なんらかのテキスト</div>

この要素があれば、これを非表示(hide)にします。

$("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/unbookmark', board: @board)) %>");

例えばこんなコードがあったとします。

HTMLから#js-bookmark-button-for-board-<%= @board.id %>というidを持つ要素を取ってきて、boardsディレクトリ内のunbookmarkをレンダリングした要素に置き換えるということをしていることがわかります。

わりと単純ですね。

$()で要素を囲うことでjQueryオブジェクト化する

何かを取ってくるときに、操作したい要素を$()で囲います。

このことで、HTMLの要素をjQueryオブジェクト化することができます。で、jQueryオブジェクトに対して任意のメソッドを呼び出してあげることができます。

(特定のクラスのインスタンスには、そのクラスが保持しているメソッドを呼び出せることに似ていますね!)

要素の指定の仕方 (「要素を指定する」)

要素の指定の仕方はたくさんあるみたいですが、とりあえずこれを覚えよう。要素を指定する文字?のことをセレクタと呼びます。要素をセレクトするための文字ということですね。

・id $('#hogehoge') 例 <div id = "hogehoge">なんらかのテキスト</div>

・class $('.foo') 例 <div class = 'foo' >なんらかのテキスト</div>

・タグ $('p') 例 <p>なんらかのテキスト</p>

これらを組み合わせて操作したい要素を取ってくることができます。指定したセレクタの条件を満たす要素をすべて取ってくることができます。

・タグ + id $('div#hogehoge') 例 <div id = "hogehoge">なんらかのテキスト</div>

・クラス + id $('#hogehoge.foo') 例 <p> id = "hogehoge" class=foo>なんらかのテキスト</p>

・タグ + クラス + id $('div#hogehoge.foo') 例 <div id = "hogehoge" class= foo>なんらかのテキスト</div>

他にも要素の階層構造を判断して、取得したい要素を特定するためのセレクタとして子孫セレクタ(ancestor descendant)なるものもあります。$('p strong')みたいにします。「pのなかのstrong要素を指定」できるというわけです。

いろんなメソッド(「それに何かをする」)

要素を指定したらいろんなメソッドが使えます。

$('セレクタ').メソッド(引数);

・show()

・hide()

・replace()

・val()

・prepend()、append()

などなど詳しくはこちらを参照

semooh.jp

$(function(){...})

ページ上にある要素を操作したいときには、すべての要素がページに読み込まれている必要があります。そうしないと、まだ読み込まれていない要素に対して操作しようとしてうまくいきません。

$(function(){...})と書くと、「ページ読み込み完了時に実行されるコードを予約する」ことができます。

$(function(){
 //なにかしらの処理
});

こんな風に書きます。

$(this)とは?

イベントが発生した要素が格納されます。クリックした要素のidを取得したいときなどに、data属性と一緒に使うことがあります。

data()でdata属性の値を取得できる

data()メソッドを使うと、取得した要素のなかのデータ属性にアクセスすることができます。例えば、複数のコメントにidが連番されているときに、そのコメントの一意の番号を取得することができます。

const commentId = $(this).data("comment-id") 

実装するときの注意点

・どの要素をどのように動かしたいのかを整理してから実装しましょう。

・変数を作成したときはconsole.logでどのような値を格納しているか、こまめに確認すること

参考文献

developer.mozilla.org

semooh.jp

qiita.com