【React✖︎Rails】ReactとRailsでマイクロサービスアーキテクチャを実装

英語喋れるようになってきたからスペイン語を学ぶ的なノリでReactを学習しようとしている23期中野昴です。

 

やっぱり、「Reactできます。」と言いたい。Vueの学習で、フロントとバックエンドを使い分けてSPAにする方法はざっくりと理解する事ができたので、これからはフロントをReact、バックをRailsでアプリを作成していきたいと思います。

 

その第一弾として、まずは環境構築から。

Vue✖︎Railsの時はRails newをして作成されたapp/javascript配下にフロントエンドのコードを書いていましたが、React✖︎Railsの構成にするということで、Dockerを使って構築していきたいと思います。

Dockerとは

異なる開発環境でもアプリケーションを素早く構築、テスト、デプロイする事ができるソフトウェア

仮想化、イメージ、コンテナという概念を理解するのに時間がかかる。いまだに掴めていないが、ざっくり、OS環境に左右されず、AWSへのデプロイや、CI/CDパイプラインが速くなるソフトウェアという認識でいる。

Docker とは | AWS

環境構築

早速dockerを使ってフロントエンド、バックエンドの環境を整えていく。

アプリを作りたいディレクトリに移動し、必要なファイルを作成していく

$ mkdir app
$ cd app
$ touch docker-compose.yml
$ touch entrypoint.sh
$ mkdir frontend
$ mkdir backend
$ cd frontend
$ touch Dockerfile

ファイルの作成

中身を作成していく

docker-compose.ymlの作成

version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
        - POSTGRES_USER
        - POSTGRES_PASSWORD
        - POSTGRES_DB
    ports:
      - "15432:5432"
  backend:
    build: ./backend/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3020 -b '0.0.0.0'"
    volumes:
      - .:/backend
    ports:
      - "3307:3306"
    depends_on:
      - db
  frontend:
    build: 
      context: ./frontend/
      dockerfile: Dockerfile
    volumes:
      - .:/frontend/
    command: sh -c "cd frontend && PORT=3001 yarn start"
    ports:
      - "3001:3001"

dockerで使用されるサービス名は、アプリ名とdb名の二つに分かれている。アプリ名は、docker-compose run <アプリ名>で使われる。

各サービス名は、わかりやすければなんでもいいでそう。

ComposeFile内の各サービス名は、わかりやすければなんでもいいですComposeFile内の各サービス名は、わかりやすければなんでもいいです

アプリ名: frontend, backend

db名: db

詳しい詳細はこの記事に書いてある。

docker-compose.ymlファイルが置かれているディレクトリでdocker-compose upを打つと、docker-compose.ymlに書かれたコードが実行される。

バックエンドの環境構築

バックエンドにRailsを採用するために、まずはapiモードのrails環境を整える。

rails newを下記のように実行

$ docker-compose run backend 
rails new  ./backend 
--force 
--no-deps 
--database=postgresql  
--api

それぞれのコマンドは、下記のような意味を持っている。

--api

アプリをapiモードで起動するオプション。viewファイルが作成されない。

--force

: 既存のGemfileを上書きするためのオプション

--no-deps

: リンクしたサービスを起動しない

--database=postgresql

: DBにpostgresqlを指定

--skip-bundle

: bundleをskip(最後にbundleします

次に、backendディレクトリにDockerfileを作成する。

Dockerfile

docker buildをターミナルで打つと、上から順番に実行されていく。

FROM ruby:2.6.7
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \\
curl -sS <https://dl.yarnpkg.com/debian/pubkey.gpg> | apt-key add - && \\
echo "deb <https://dl.yarnpkg.com/debian/> stable main" | tee /etc/apt/sources.list.d/yarn.list && \\
apt-get update && apt-get install -y yarn

# Node.jsをインストール
RUN curl -sL <https://deb.nodesource.com/setup_14.x> | bash - && \\
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1655A0AB68576280 && \\
apt-get update && \\
apt-get install -y nodejs

#backendディレクトリを作成する
RUN mkdir /backend
WORKDIR /backend
#Railsで使うGemをインストールする
COPY Gemfile /Gemfile
COPY Gemfile.lock /Gemfile.lock
RUN gem install bundler
RUN cd /backend
RUN bundle install
COPY . /backend

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3020

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

yarn,node,ruby gemsがインストールされる。一気にイメージが作られるところはかなり壮観だから一度試して欲しい。

各Dockerコマンドの意味

RUN

コマンドを実行する。

WORKDIR

WORKDIR 命令は、Dockerfile 内で以降に続く RUN 、 CMD 、 ENTRYPOINT 、 COPY 、 ADD 命令の処理時に(コマンドを実行する場所として)使う 作業ディレクトリworking directory を指定する。

DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】 - Qiita

Rails API × React × TypeScriptで作るシンプルなTodoアプリ - Qiita

フロントエンドの環境構築

フロントはreactにするため、Reactをインストールするコマンドを打つ。

すでにdocker-compose.ymlのfrontendというサービス名の配下にビルドの流れが描かれているため、下記コマンドをdocker-compose.ymlのあるディレクトリで打つだけでいい。

$ docker compose run --rm 
frontend sh -c 
"yarn global add create-react-app && 
create-react-app ./frontend 
--template typescript"
—rm

コンテナを停止した段階で削除してくれるコマンド。

frontend

frontendというディレクトリ名でreactアプリが作成される。

sh -c "yarn global add create-react-app

sh -cに続くコマンドを実行。yarn global add create-react-appで、reactをインストールするパッケージをダウンロードしている。

create-react-app ./frontend 

先程作成したfrontendディレクトリでreactアプリを展開させる

--template typescript"

jsファイルに、typescriptを使う。

Dockerfileに書き込む。

FROM node:14.4.0-alpine3.10
WORKDIR /frontend

最後にコマンドを実行

dockerを起動するときは、下記コマンドを実行すればいい。

$ docker-compose up --build

これで、下記のようなファイル構成のアプリが完成する

Image from Gyazo

【React】Docker Composeで開発環境を構築

番外編

bundle installに苦しむ

bundle installが実行されないため、backendディレクトリに移動して、わざわざdocker-compose run backendと打たないといけない。

Docker Compose + Railsでイメージ内でbundle installしているはずなのにgemが無いとエラーがでる。 - Qiita

React + Rails API モードで基本的な CRUD アプリを作ってみた (バックエンド編)

node.jsのインストールに苦しむ

node.jsが正常にインストールされないエラーに当たることがある。実際に私はあたった。その時は、エラー文をそのままブラウザに打ち込むとこの記事が出てくるので、node.jsをインストールする記述を変更してあげると見事にエラーが無くなることを確認する事ができる。

具体的に、下記コマンドを付け加えてあげると良い。

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1655A0AB68576280 && \\
apt-get update && \\

Dockerにnodejsをインストールするとエラーになった

Node - Official Image | Docker Hub

【Ruby】Procオブジェクト

javascriptRubyでいうところのProcのような書き方が多いんだよね〜」と村田講師から教えていただいたが、そもそもProcがわからないので今回はrubyのProcオブジェクトを学習していきます。

 

前提知識

procを学習する前に、いくつか頭に入れておかないといけない前提知識があるみたいで。

  • Rubyの関数(メソッド)は直接変数に代入したり、他の関数に渡す事ができない。
  • Rubyの関数(メソッド)を変数に代入したり、他の関数に渡すためには、関数をObject#methodでラップする必要がある。・・・①
  • Object#methodでラップしたメソッドを実行させるためには、Object#callを実行させる必要がある。・・・②
  • ②を別の関数に引き渡すこともできる。・・・③
def square(n)
  n * n
end

sq = method(:square)・・・①

sq.call(3) # => 9・・・②

def print_func(arg, fun)・・・③
  puts fun.call(arg)
end

print_func(4, sq)

# >> 16

無邪気な少年A: 関数Aを関数Bに渡したいです!

Rubyさん: じゃあこの2つの手続きを踏むといいよ

  1. 関数Aをmethodで囲む。
  2. 1で加工した関数Aを関数Bの引数に入れ、関数の中身でcallする

ブロック

do...endや{}で囲まれた塊のこと。

def print_func(arg, &fun)
  puts fun.call(arg)
end

#do..endで書いた場合
print_func(4) do |n|
n * n
end
# >> 16

#ブロックで書いた場合
print_func(4) { |n| n * n }

# >> 16

yield

ブロックの説明で書いていた& + call を yieldで表現できるようになる。

def print_func(arg)
  puts yield(arg)
end

#do..endで書いた場合

print_func(4) do |n|
n * n
end
# >> 16

#ブロックで書いた場合

print_func(4) { |n| n * n }

# >> 16

Procとは

ブロックをコンテキスト(ローカル変数のスコープやスタックフレーム)とともにオブジェクト化した手続きオブジェクト

何ができる?

ブロックを他の関数に渡す事ができるらしい。

ブロックをProcオブジェクトにするにはlambdaprocProc.new->の何れかを使う。

lambda { **|**n**|** n ***** n } *# => #<Proc:0x007f89a1852960@-:13 (lambda)>*

proc { **|**n**|** n ***** n } *# => #<Proc:0x007f89a18526b8@-:14>*

Proc.**new** { **|**n**|** n ***** n } *# => #<Proc:0x007f89a1852438@-:15>*

**->**n{ n ***** n } *# => #<Proc:0x007f89a1852190@-:16 (lambda)>*

それぞれが下記のような特徴を持つ

							return                     next                     break
Proc.new    メソッドを抜ける            手続きオブジェクトを抜ける  例外が発生する
proc        メソッドを抜ける            手続きオブジェクトを抜ける  例外が発生する
lambda      手続きオブジェクトを抜ける   手続きオブジェクトを抜ける  手続きオブジェクトを抜ける
イテレータ   メソッドを抜ける            手続きオブジェクトを抜ける  メソッドを抜ける

以下のような感じでyieldと組み合わせてブロックを渡すもしくは代入する事ができる。

square = ->n{ n * n }・・・"->"でprocしている。

square.call(3) # => 9 ・・・callでprocを実行させる事ができる

def print_func(arg,fun)
  puts fun.call(arg)
end

print_func(4, square) 

# >> 16

procオブジェクトはそれ自体に名前がないため、無名関数と呼ばれる。

def print_func(arg, fun)
  puts fun.call(arg)
end

print_func(4,->n{ n* n })

# >> 16

まとめ

  • procオブジェクトはブロックを他の関数に渡すための無名関数
  • 関数を変数に入れて実行する場合や、他の関数に渡す場合は、Object#methodでラップし、Object#callで実行させればいい。

一言

ざっくりとしかprocを知れてなかったけど、今回procを学習したおかげでこれからはrailsにスッキリとしたコードが書けるような気がしてきた!

Procを制する者がRubyを制す(嘘)

【初心者向け】RailsAPIモードでCRUD処理を実装する方法

徒歩3分圏内にQBハウスがあることによって散歩ついでに散髪に行くことが可能になった23期スキンフェード昴です。

 

さて、今回はモダンなアプリ開発に欠かせない、rails apiモードに関して学習していきたいと思います。ちょっと長いです。

上から順に見ていくと、rails apiモードでデータのcrud処理ができるようになります。

いわゆるバックエンドにrails、フロントエンドにjavascriptのライブラリ(ReactやVueなど)の構成でアプリを作ることもできるんです。すごいです。rails apiモード。

では、早速開発を進めていきたいと思います。

 

開発環境

rails  6.1.4
ruby   2.6.7
node   12.22.6
mysql  5.7.36

apiモードでrails new

Rails APIモードとは、API作成に特化したモードのことです。

APIモードではMVCのV(ビュー)が存在しないため、rails newを実行した際にビューに関するファイルやGemが生成されません。

apiモードでrails newを実行すると、viewを生成しなくなる。APIモード = JSONを返すモードと解釈してもいいらしい。今回は、mysqlをDBとして扱う。

$ rails  new api-sample -d mysql --api

db作成

$ rails db:create
Running via Spring preloader in process 64897
Created database 'api_sample_development'
Created database 'api_sample_test'

CORS(Cross-Origin Resource Sharing)の設定

ざっくり説明すると、 デフォルトでは、React等の別のオリジンからRailsAPIにアクセス(GETPOSTPUTDELETEなど)することは制限されています

フロントとバックで切り分けることはsame origin policyに反した行為だそう。Webページを生成したドメイン以外へのHTTPリクエストへアクセス(クロスドメインアクセス)したい場合に有用なのがCORSとのこと。クロスドメインアクセスを実現する事ができる。

具体的に、config/initializer配下にcors.rbを作成することで、クロスドメインアクセスを実現できる。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
      origins '<http://localhost:3000>'
  
      resource '*',
          headers: :any,
          methods: [:get, :post, :put, :patch, :delete, :options, :head],
          credentials: true
    end
  end

Pumaの設定

バックエンドのport番号と被ることを防ぐために3010に変えておく。

portENV.fetch("PORT") { 3010 }

適当なモデルの作成

自分の好きなモデル名、カラム名を任意で作成する

rails g model Alcohol name:string alcohol_percentage:integer price:integer
rails g model Customer name:string favorite_alcohol:string
rails g model Owner name:string
rails g model Shop name:string

rails-erdで作成したDB設計図

Image from Gyazo

サーバーにアクセスしてみる

rails s

お馴染みのyay you’re on railsが表示される

Image from Gyazo

ルーティングの構成を確認

それぞれCRUDができる状態になっている

routes.rb

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :customers, only: %i[index create update destroy]
      resources :shops, only: %i[index create update destroy]
      resources :alcohols, only: %i[index create update destroy show]
      resources :owners, only: %i[index create update destroy]
    end
  end
  # For details on the DSL available within this file, see <https://guides.rubyonrails.org/routing.html>
end

コンソールでも確認してみる。

$rails routes --expanded
--[ Route 1 ]--------------------------------------------------------------------------------------
Prefix            | api_v1_customers
Verb              | GET
URI               | /api/v1/customers(.:format)
Controller#Action | api/v1/customers#index
--[ Route 2 ]--------------------------------------------------------------------------------------
Prefix            | 
Verb              | POST
URI               | /api/v1/customers(.:format)
Controller#Action | api/v1/customers#create
--[ Route 3 ]--------------------------------------------------------------------------------------
Prefix            | api_v1_customer
Verb              | PATCH
URI               | /api/v1/customers/:id(.:format)
Controller#Action | api/v1/customers#update
--[ Route 4 ]--------------------------------------------------------------------------------------
Prefix            | 
Verb              | PUT
URI               | /api/v1/customers/:id(.:format)
Controller#Action | api/v1/customers#update
--[ Route 5 ]--------------------------------------------------------------------------------------
Prefix            | 
Verb              | DELETE
URI               | /api/v1/customers/:id(.:format)
Controller#Action | api/v1/customers#destroy
--[ Route 6 ]--------------------------------------------------------------------------------------
Prefix            | api_v1_shops
Verb              | GET
URI               | /api/v1/shops(.:format)
Controller#Action | api/v1/shops#index
--[ Route 7 ]--------------------------------------------------------------------------------------
Prefix            | 
Verb              | POST
URI               | /api/v1/shops(.:format)
Controller#Action | api/v1/shops#create
--[ Route 8 ]--------------------------------------------------------------------------------------
Prefix            | api_v1_shop
Verb              | PATCH
URI               | /api/v1/shops/:id(.:format)
Controller#Action | api/v1/shops#update
--[ Route 9 ]--------------------------------------------------------------------------------------
Prefix            | 
Verb              | PUT
URI               | /api/v1/shops/:id(.:format)
Controller#Action | api/v1/shops#update
--[ Route 10 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | DELETE
URI               | /api/v1/shops/:id(.:format)
Controller#Action | api/v1/shops#destroy
--[ Route 11 ]-------------------------------------------------------------------------------------
Prefix            | api_v1_alcohols
Verb              | GET
URI               | /api/v1/alcohols(.:format)
Controller#Action | api/v1/alcohols#index
--[ Route 12 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | POST
URI               | /api/v1/alcohols(.:format)
Controller#Action | api/v1/alcohols#create
--[ Route 13 ]-------------------------------------------------------------------------------------
Prefix            | api_v1_alcohol
Verb              | PATCH
URI               | /api/v1/alcohols/:id(.:format)
Controller#Action | api/v1/alcohols#update
--[ Route 14 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | PUT
URI               | /api/v1/alcohols/:id(.:format)
Controller#Action | api/v1/alcohols#update
--[ Route 15 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | DELETE
URI               | /api/v1/alcohols/:id(.:format)
Controller#Action | api/v1/alcohols#destroy
--[ Route 16 ]-------------------------------------------------------------------------------------
Prefix            | api_v1_owners
Verb              | GET
URI               | /api/v1/owners(.:format)
Controller#Action | api/v1/owners#index
--[ Route 17 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | POST
URI               | /api/v1/owners(.:format)
Controller#Action | api/v1/owners#create
--[ Route 18 ]-------------------------------------------------------------------------------------
Prefix            | api_v1_owner
Verb              | PATCH
URI               | /api/v1/owners/:id(.:format)
Controller#Action | api/v1/owners#update
--[ Route 19 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | PUT
URI               | /api/v1/owners/:id(.:format)
Controller#Action | api/v1/owners#update
--[ Route 20 ]-------------------------------------------------------------------------------------
Prefix            | 
Verb              | DELETE
URI               | /api/v1/owners/:id(.:format)
Controller#Action | api/v1/owners#destroy

アルコールを作成してみる

コントローラーの構成

api/v1/alcohols_controller.rb

class Api::V1::AlcoholsController < ApplicationController
  def index
    @alcohols = Alcohol.all
    render json: @alcohols
  end

  def show
    @alcohol = Alcohol.find(params[:id])
    render json: @alcohol
  end
    def create
    @shop = Shop.find(1)
      @alcohols = @shop.alcohols.new(alcohol_params)
      if @alcohols.save
      render json: @alcohols
      else
        render nil
      end
  end

  def update
    set_alcohol
    if @alcohol.update(alcohol_params)
      render json: @alcohol
    else
      render nil
    end
  end

  def destroy
    set_alcohol
    @alcohol.destroy!
    render json: @alcohol
  end
  private
  def set_alcohol
    @alcohol = Alcohol.find(params[:id])
  end

  def alcohol_params
    params.require(:alcohol).permit(:name, :price, :alcohol_percentage)
  end
end

Curlを使ってデータを作成(post)してみる

$ curl -X POST -H "Content-Type: application/json" -d '{"name": "ビール" : "alcohol_percentage": 5 : "price" : 500}' <http://localhost:3000/api/v1/alcohols>

Curlを使って作成したアルコールを取得(get)してみる

$ curl <http://localhost:3010/api/v1/alcohols>
[{"id":1,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":500,"created_at":"2022-01-05T12:49:27.927Z","updated_at":"2022-01-05T12:49:27.927Z"},{"id":2,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":1000,"created_at":"2022-01-05T12:52:35.709Z","updated_at":"2022-01-05T12:52:35.709Z"},{"id":3,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":500,"created_at":"2022-01-05T12:53:32.557Z","updated_at":"2022-01-05T12:53:32.557Z"}]SubarunoMacBook-puro-3:api-sample subaru$

ブラウザにURLを打ち込んで直接アクセスすることもできる

Image from Gyazo

Curlを使って作成したアルコール詳細(show)を取得(get)してみる

$ curl <http://localhost:3010/api/v1/alcohols/1>
{"id":1,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":500,"created_at":"2022-01-05T12:49:27.927Z","updated_at":"2022-01-05T12:49:27.927Z"}

$ curl <http://localhost:3010/api/v1/alcohols/2>
{"id":2,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":1000,"created_at":"2022-01-05T12:52:35.709Z","updated_at":"2022-01-05T12:52:35.709Z"}

Curlを使って作成したアルコールを削除(delete)してみる

$ curl -X DELETE <http://localhost:3010/api/v1/alcohols/1>
{"id":1,"name":"ビール","alcohol_percentage":5,"shop_id":1,"price":500,"created_at":"2022-01-05T12:49:27.927Z","updated_at":"2022-01-05T12:49:27.927Z"}

Curlを使って作成したアルコールの情報を更新(put)してみる

$ curl -X PUT <http://localhost:3010/api/v1/alcohols/2> -d 'alcohol[name]="濃いめのレモンサワー"&alcohol[price]=400&alcohol[alcohol_percentage]=5'
{"name":"\\"濃いめのレモンサワー\\"","price":400,"alcohol_percentage":5,"id":2,"shop_id":1,"created_at":"2022-01-05T12:52:35.709Z","updated_at":"2022-01-05T13:21:06.296Z"}

まとめ

  • バックエンドをrailsapiモードで実装することで、フロントエンドにjavascriptのライブラリ(ReactやVue)を使用する事が容易になる。
  • Apiのレスポンスやリクエストを試す際には、CurlやPostmanが便利

【Rails】Rails6でAPIモードの環境構築をしっかりやる

https://github.com/r7kamura/autodoc

https://github.com/ruby-grape/grape

RailsでAPIを作成するために色々比較したので所感と実装方法のご紹介 - Qiita

React + Rails API モードで基本的な CRUD アプリを作ってみた (フロントエンド編 その1)

RailsのAPIモードを試してみた話 - のんびりきままな開発日記

【初心者むけ】slim記法

最近脚がものすごく強くなっていること23期インナーサイ79kg挙がるです。

 

現場ではslimが使われているからslimを使おうと現場railsに書いてあったことを思い出したので、今回はslim記法に関して学習していきたいと思います。

slimとは

rubyの記法の一つ。他にはerb,haml,jadeなどの書き方がある。<>がいらない事が最大の特徴。

https://github.com/slim-template/slim

早速書き方を覗いてみる。

<div></div>
<html></html>
<meta></meta>
<header></header>
<footer></footer>
<table></table>
<h1></h1>
<p></p>
<a><a>
<ul></ul>
<li></li>

上記のerb記法は、下記のように、<>を無くしてスリムに書く事ができる。

div
html
meta
header
footer
table
h1
p
a
ul
li

slim公式に書いてあった下記記述例を読み解きながらslimに慣れていきたい。

html
  head
    title Slim Examples
    meta name="keywords" content="template language"meta name="author" content=author
    link rel="icon" type="image/png" href=file_path("favicon.png")
    javascript:
      alert('Slim supports embedded javascript!')

  body
    h1 Markup examples

    #content
      p This example shows you how a basic Slim file looks.

    == yield

    - if items.any?
      table#items
        - for item in items
          tr
            td.name = item.name
            td.price = item.price
    - else
      p No items found. Please add some inventory.
        Thank you!

    div id="footer"
      == render 'footer'
      | Copyright &copy; #{@year} #{@author}

上から読み解いていく。

#slim
html
  head
    title Slim Examples
    meta name="keywords" content="template language"meta name="author" content=author
#erb
<html>
  <head>
    <title> Slim Examples</title>
    <meta name="keywords" content="template language"meta name="author" content=author />
</head>
</html>

インデントを一つ間違えるだけでエラーになってしまう。

<aside> 💡 slimはインデントに厳しい

</aside>

#slim
link rel="icon" type="image/png" href=file_path("favicon.png")
#erb 
<a link rel="icon" type="image/png" href=file_path("favicon.png")>

javascript

  javascript:
      alert('Slim supports embedded javascript!')
<script>
  alert('Slim supports embedded javascript!')
</script>

id


#content
      p This example shows you how a basic Slim file looks.
<p id="content">This example shows you how a basic Slim file looks.</p>

Rubyコード

 == yield
<%= yield %>

if文

#slim
    - if items.any?
      table#items
        - for item in items
          tr
            td.name = item.name
            td.price = item.price
    - else
      p No items found. Please add some inventory.
        Thank you!
#erb
<% if items.any?>
 <table id="items">
  <%for item in items %>
   <tr>
     <td class="name"><%=item.name%>
     <td class="price"><%=item.price%>
<% else%>
  <p>No items found. Please add some inventory.Thank you!</p>
<%end%>

|

#slim
 div id="footer"
      == render 'footer'
      | Copyright &copy; #{@year} #{@author}
#erb
 <div id="footer">
  <%=render 'footer'%>
		Copyright &copy;#{@year} #{@author}
</div>

まとめ

・<>がいらない

・テキストは |の後ろにかく。

・if → -

・<%= %> →  =

・<% %> → -

・コメント → /

・id指定 → #

・class指定 → .

【爆速で習得】Railsでslimを使う方法から基本文法まで - Qiita

slimの書き方をマスターしよう!

【Web技術】TCP/IPとは

新宿のビックロで電気ストーブを購入したのでこの冬は生存できること確定した23期酒ジュール作成中です。

さて、今回は、Webの技術にあるTCP/IPの中のアプリケーション層に関して学習していきたいと思います。

TCP/IPとは

現在のインターネット通信およびイントラネット通信において最も利用されている通信プロトコル

TCP/IPは複数のプロトコルからなっているが、中心的な役割を果たすのがTCPとIPであることから

TCP/IPという名前になっている。

TCP/IPの階層は、上から「アプリケーション層」「トランスポート層」「インターネット層」「ネットワークインターフェイス層」の4層に分かれている。

アプリケーション層とは

TCP/IPの4層目。人間が扱う場所に一番近い階層HTTP,HTTPS,SMTP,POP3,IMAP4,DHCP,DNSなどが存在する。

アプリケーションで扱うデータのフォーマットや手順を決める役割を担っている。

アプリケーションは基本的には人間が扱うため、文字や画像など人間が認識できるようにデータを表現している。主なプロトコルは「HTTP」「SMTP」「POP3」「IMAP4」「DHCP」「DNS」。HTTPはWebブラウザで利用し、SMTPPOP3は電子メールソフトで利用する。また、DHCPDNSはアプリケーション通信を行うための準備のプロトコルとして補うことを担っている。

TCPとは

OSI参照モデルトランスポート層にあたるプロトコルで、インターネット等で利用される。信頼性は高いが転送速度が低いという特徴がある。

簡単に解釈すると、

「送ったデータが相手に届いたか、その都度確認しながら通信するやり方」や「正確な信号を送信する通信の規格を定めたもののことを指すみたい。

IPとは

IPアドレスと呼ばれる数値を付与しその数字を用いて通信先の指定及び呼び出しを行いネットワーク通信を行うこと。

IPアドレスにはIPv4IPv6が存在し、記述の仕方が異なっている。

 

「Decoratorがプレゼンテーション層を担っている」と聞き、プレゼンテーション層ってなんだ?と疑問に思ったことをきっかけにTCP/IPについて調べました。

当初はTCP/IPの中にプレゼンテーション層があると思っていました。しかし、OSI参照モデルの第6層(レイヤ6/L6)に位置し、TCP/IP階層モデルDARPAモデル)では階層としては存在しない事が判明。Webに関する知識を補強しないとなと思いました。。

TCP/IPとは?通信プロトコルの階層モデルを図解で解説 | ITコラム|アイティーエム株式会社

アプリケーション層のプロトコル一覧

【就活】エンジニアのキャリアパスを✅

zerokenの可愛い初代iconが出来上がりました!名付けてゼロ犬です笑

Image from Gyazo

5年後、10年後にはどんなエンジニアになっていたいですか?という問いに答えられなそうなので、今のうちに考えておきたいと思います。

そのためには、どんなキャリアパスがあるのかを知っておくべき。なので、今回は、キャリアパスに関して学習していきたいと思います。

主に、技術のスペシャリスト・ビジネスマネジメントエンジニアの二つがあるそう。

技術のスペシャリスト

ITスペシャリスト

ITスペシャリストは、IPA(独立行政法人情報処理推進機構)が定めるITスキル標準ITSS)で定義されている以下の6つの専門分野においてレベル3以上を満たす高度な専門性を持つエンジニアのことを指すらしい。

  • プラットフォーム
  • ネットワーク
  • データベース
  • アプリケーション共通基盤
  • システム管理
  • セキュリティ

何かを作り出すというより、会社のシステムを守る人って感じだろうか。社内の縁の下の力持ち、GK的存在。

テックリード

窓口の役割として、エンジニアチームと他部署などをつなぐコミュニケーション力が求められ、技術面ではエンジニアチームのリーダーとして、高度な技術力が求められる。

CTOと何が違うのだろうか?

CTOとは最高技術責任者です。組織の中で最も高い技術力が要求され、経営のトップレベルです。テックリードはチーム単位のリーダーであるため、エンジニアをまとめるポジションです。

ふむふむ。テックリードは部長で、CTOは社長的な感じだろうか。テックリード→CTOという流れでキャリアを歩んでいくんだな。

フルスタックエンジニア

開発に関しては一人で全ての事ができるエンジニアを指す。全ての事とは、下記のことを指している、

  • バックエンド・フロントエンドの開発スキル
  • モバイルサービス関連スキル
  • クラウドサービス関連スキル
  • マネジメントスキル
  • 要件定義
  • 基本設計
  • 開発
  • テスト
  • 保守・運用

スタートアップのような人材の少ない会社において重宝されそう。重宝されるということは希少価値の高い人材であるため、給料が高くなる傾向にある。でも、大変そうだな〜。

CTO

最高技術責任者であり、その名の通り組織の中で最も高い技術力が要求される

高度な技術力にプラスして、自分の強みとなるスキル(コミュニケーション、経営、マーケティング、マネジメントなど)を持ち合わせていることも必要。

オールラウンダーということだろうか。

フロントエンドエンジニア

Webサイトのブラウザ上で動作する機能の制作を担当

主にjavascriptを取り扱う人と捉えて良さそう。最近はPaasとNextというように、サーバーとフロントを一気にやってくれるjavascriptも出てきたから、垣根がなくなりつつあるそう。とりあえずjavascriptが触れれば食いっぱぐれないっぽい。

サーバサイドエンジニア

サーバの設計・構築、保守・運用にかかかわる

その後のキャリアパスとしてネットワークエンジニアやITアーキテクト、プロジェクトマネージャーがある。

キャリアパスが明確なのはいいな。やはりPMだろうか。かっこいい。

ビジネス・マネジメント

ITアーキテクト

ITアーキテクトは、ITスペシャリストに経営的視点を加えた専門家の総称であり、システムやプロジェクトの「設計」する役割を担う。

PL/PM

プロジェクトマネージャー目指すには、下記のようなキャリアパスを通ることが多いでしょう。いずれのポジションも、技術的な背景を理解していることが求められます。

  • プログラマーとして開発経験・技術力を積む
  • システムエンジニアとしてコミュニケーション力や設計技術などのスキルを身に着ける
  • プロジェクトリーダーとしてマネジメント力・リーダーシップ力を磨く
  • プロジェクトマネージャー

VPoE

VPoE(VP of Engineering)とは、開発チーム、エンジニアチームのマネジメント責任者です。エンジニアの採用、育成、組織の設計など、エンジニア組織のマネジメントが業務の軸となります。

Webディレクター

Webサイト構築の際、プロジェクトの監督、管理、進行を行う立場の人を指します。主に制作チームのメンバーとコミュニケーションを取りながら、プロジェクトが円滑に進むように管理します。

う〜ん。サーバーサイドを触りつつ、フロントの言語も触れるようになって、フルスタック⇨テックリード⇨CTOというキャリアパスが一番良さそうな気がする、、起業する時に全部自分でできたら楽しそうだし、教育も楽しそう。

【2021年】23歳⇨24歳。厄年を✅

現役エンジニア3人、運営一人と飲んで自分も現役エンジニアになったと勘違いしている23期早くエアコンを買いたいこと寝るときはダウン3枚着てるです。

 

宣伝

ZEROKENをリリースいたしました!

サイトURL

https://www.zeroken.site/

Image from Gyazo

簡単にお酒の強さを測る事ができて、アルハラを予防する事ができるアプリになります!

自分に合ったお酒の飲み方の順番を見つけて自分のペースで飲み会を乗り切ってください!

 

今日は12月31日ということで、2021年1月から12月までの一年を振り返っていきたいと思います。

さて、どんな一年だったのでしょうか。

2021年1月

出来事

  • html,cssを学習し始める。
  • 彼女が出来る
  • 資格を3つ取得。
  • トライアスロンチーム「iron will」に加入する
  • 転職に向けた企業探しを始める
  • トライアスロン用のバイク「Giant」を11万で購入する

心境

  • 1997年生まれは厄年だと聞き、「うわ、不安を煽ってお守りを交わせるタイプのやつだ。神社もマーケティングするんだな〜」と感じる。
  • 一緒にいて楽しい、笑顔可愛い、癒されるという3点に魅力を感じ彼女(今の彼女)と付き合った。
  • 生涯スポーツだから一生かけて自己記録を更新できそう。自分の限界を知りたいと思いトライアスロンを始める。
  • とりあえずmy naviのIT企業を片っぱしから応募してみる。
  • iron willの人が25%引で売ってくれるというので新品のGiantを購入。サドルが硬いことにイライラ。一漕ぎの推進力に驚きを感じる。

2021年2月

出来事

  • プログラミングスクールの説明会に複数応募(G’s academy,DMM ,RUNTEQ,GEEK JOB)。結局どこも入会せず。
  • 英検1級に落ちる。2028点合格のところ2004点だった。
  • ルービックキューブ6面を1分30秒で揃える事ができるようになる。
  • 転職先が決まる。
  • 吉祥寺のシェアハウスに移住を決める
  • 甥っ子に初めて会う。

心境

  • プログラミングと1年ぶりの再会を果たす。htmlにcssを使って色をつけられたことに感動をしていた。
  • 意外と英検1級ってちょろいと思っていた。正答率7割を超えたのに落ちてイライラ。
  • 転職先では最初の6ヶ月間でphpを学習し、その後はSESになる事ができると聞いていた。ワクワクが止まらなかった。
  • 新しい住居の下見をしてワクワク。外国人が多いため、英語の勉強になっていいかな。
  • 甥っ子が可愛い。

2021年3月

出来事

  • 将来起業するためには何をすればいいのかと本気で考えるようになる。「LIFE SHIFT」「WORK SHIFT」を読む。
  • 課長、次長、支店長に退職を告げる。
  • マナブログに感化されてword pressでブログを始める。
  • 食事に興味を持つ。オートファジーで暮らすために16時間のプチ断食を始める。7日で終了。空腹には耐えられないと悟る。
  • 両学長にハマる。長期投資、格安スマホ、FIREに興味を持つ。

心境

  • 「100年ある人生を幸せに生きるためにはどうすればいいか」を漠然と考えていた。割と迷走していた。
  • 月5万稼げる副業に興味を持っていた気がする。それゆえ、マナブログ、両学長、中田敦彦Youtube大学、西野孔明エンタメ研究所などにハマっていた。
  • 退職を告げる時は、好きな人に告白をする時のように緊張した。浮き足立っていたような気がする。10年目に年収が1000万円になる会社を辞めるんだ俺は。すごい決断をしているんだ。と息巻いていた。
  • プチ断食をすることで体内の炎症を抑えることに興味を持っていた。

2021年4月

出来事

  • 転職をする。
  • phpを学習し始める。サイト作成に勤しむ。
  • ふるさと納税を頼む。
  • 高配当株に興味を持つ。SPYD、VOOを一括購入する。
  • 陸上を再開し始める。

心境

  • phpが難しい。ログイン機能に苦戦。<? echo hoge?>の記述に目が慣れてきたな。
  • html,cssのレスポンシブ対応にイライラ。
  • シェアハウスにreactでアプリを作ったという大学3年生がいることを知る。

2021年5月

出来事

  • Reactを使ったアプリ作成に興味を持つが、挫折。
  • SQLが分からない。
  • 横浜国際トライアスロンに初出場。
  • Web制作とWeb開発の違いを理解し始める
  • 案件先がテレアポの会社になる。もちろん業務中にコードはさわれない。

心境

  • 6ヶ月かかるカリキュラムが意外と2ヶ月くらいで終わりそうだな。ポートフォリオを作成するフェーズに入ったが、作るイメージがわかない。
  • 退社の意向を固める

2021年6月

出来事

  • Ruby on Railsを学習できるプログラミングスクール(RUNTEQ,Fyord BootCamp)を探し始める。
  • 退職の意向を伝える。
  • 40kgのダンベルをAmazonで購入。毎日筋トレ生活が始まる。
  • 現場Railsを始める

心境

  • RUNTEQがいいらしい。amazon株を売却して得た資金で入学金を工面。
  • なりたい自分になれないというかなり曖昧な理由で退職を伝える。

2021年7月

出来事

心境

  • sorcery課題が尋常じゃないくらいに難しい。というより、環境構築が出来なくてイライラ。

2021年8月

出来事

  • 高校で部活が同じだった同士と本格的に陸上競技を始める。
  • 彼女の誕生日を祝う。
  • アプリ「Optime」をリリースする。

心境

  • 陸上競技を通じて運命的な出会いを果たした。人生何があるか分からないな。
  • 彼女が可愛い
  • 個人開発が面白い。

2021年9月

出来事

  • 10月からシェアハウスの家賃が2万引上ることに。陸上の同志と競技場から近い武蔵小杉に引っ越さないかと提案をする。そして引っ越し。
  • RUNTEQカリキュラム応用篇が終了。READMEの作成に入る。

心境

  • 新生活にワクワク。武蔵小杉タワマン多すぎやろ。引っ越し先にエアコンがついていないことに気がつく。なんとかなるだろうと考える。
  • いよいよアプリの作成だ〜ワクワク。飲み会で飲むお酒の順番を診断するアプリにしよう。そうだな、名前は「Preliquo」にしよう。

2021年10月

出来事

  • 陸上生活3ヶ月目。現役の時の感覚が戻ってくる。
  • ポートフォリオを作成し始める。
  • Vueが分からない。
  • MySQLのエラーに1週間費やす。

心境

  • 思ったよりアプリの完成が進まなくて焦る。診断系はjavascriptを使って動きをつけたほうが離脱率が下がると聞いたからVueを使った。しかし、キャッチアップに時間がかかりすぎていると感じている。
  • MySQLのエラーに泣かされる。何度もブランチを切るハメに。

2021年11月

出来事

  • なんとなくVueを理解し始める。Rubyを使って開発をすれば良かったと後悔。
  • JSONの加工に苦しむ。
  • MVPをリリースする。

心境

  • プルリクエストは早い段階で作成して講師の方々に質問をすれば良かった。
  • なんとか診断機能が完成してMVPをリリースする事ができた。だが、診断結果表示がぐちゃぐちゃ。なんとかしなきゃ。
  • ベンチプレスがすごい上る。体が大きくなり始める。

2021年12月

出来事

  • もくもく会に参加し始める。
  • ブログ連続投稿が120日を超える。
  • アプリをリリースする。
  • 将来のお医者さん達と何故か砂浜練習をする
  • 現役エンジニアと運営に囲まれたパーティに参加する。
  • コスパの良いシェアオフィスを見つける。
  • 業務委託の話をいただく

心境

  • 流石に暖房がないと死ぬんじゃないかと焦り始める。
  • 就職できそうな未来が見えてきて少し嬉しい。
  • ベンチプレスが100kg上がったぞ。マッチョの仲間入りや。

総括

24年生きてきた中で一番苦労した。忘れられない一年になったかなと思います。

厄年にビビって過ごした一年だったので、来年は伸び伸びと生きたいと思います。

飛躍の年になりますように。

では、良いお年を。