- 投稿日:2020-02-07T22:31:16+09:00
Rails Params
- 投稿日:2020-02-07T21:23:42+09:00
Railsで部分テンプレートを使用時、Missing テンプレートエラーが出た際、解決したこと
Missing partial shared/_header with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:っというエラーが発生した際、どう解決したのか
erbファイルに部分テンプレートを書く際は、基本 <%= render 'ファイル名' %> でよかったはず・・・・
以下参照(ピカワカさんありがとうございます)
https://pikawaka.com/rails/partial_template以上のような階層です。
部分テンプレートを当てたい場所と、使用するテンプレートについて
テンプレート化したいものはsharedファイルの中にある
_header.html.erb っというファイル部分テンプレートを使用する場所は
new.html.erbファイルをまたいでいるため、shared/テンプレ化したファイル名
っという記述であってるはず・・・・っと思ったが、
devise/shared/headerっというファイルを指定したら解決
<%= render "devise/shared/header" %>上記の通り上の階層のdeviseを指定すると、部分テンプレートを使用できた。
謎でしたが・・・・とにかく解決した!10分くらいで解決したのが幸い。ここは違う、ここはこうしたほうが良い等々ございましたらご指摘いただけますと幸いです。
最後までみていただきありがとうございます。
- 投稿日:2020-02-07T21:08:47+09:00
Rails ヘルパーメソッド
主にview(ビューファイル)でHTMLタグを出現させたりテキストを加工するために予めメソッド。セキュリティ対策、コードをシンプルにする効果がある。form_tag(投稿ページなどにおけるフォームの実装)、link_to(リンクの実装)、simple_format(投稿した文章を自動で見やすく整形する)などがある。
form_tagを利用する場合
ヘルパーメソッドはRubyとして取り扱われるので、<%= %>(erbタグ)で囲んで使用する。/postsはルーティングのURIパターン、method: :postはHTTPメソッドを表す。
ビューファイルに実装する。
例:新規投稿ページにアクセスするためのリンクを追加
リンクに表示する文字は新規投稿、リンク先のURLはhttp://localhost:3000/posts/newを使用。/posts/newと省略することもできる。form_with メソッド
特徴は3つある。
自動でパスを選択してくれて、HTTPメソッドを指定する必要が無い。
コントローラーから渡された、ActiveRecordを継承するモデルのインスタンスが利用できること(上記では@postがそれに該当)
inputタグは用いない。ストロングパラメータを用いた場合
リダイレクト処理
バリデーション
データを登録する際に、一定の制約をかけること。
例:post.rb
これでタイトルと本文のいずれかが空の場合は保存処理が行われない。
simple_format メソッド
投稿時に改行を含むデータを送信したときに、その改行を反映してくれる役割がある。
- 投稿日:2020-02-07T20:24:27+09:00
人の感情を可視化するアプリを作りました【キドアイラク】
はじめに
皆さん初めまして!
本記事は私がrailsで作った初めてのアプリである「キドアイラク」の紹介記事になっています。
https://kidoairaku2019.herokuapp.com
この「キドアイラク」がどのようなアプリかというと、タイトル通り「人の感情を可視化する」アプリです。
自分がここ数日どんな感情で過ごしていたのか、他の人はどんな時にどんな感情を抱くのかを一目で確認することができます。
街中を歩く一人一人の感情が透けて見えるイメージです。
本サービスを作った背景や機能は後ほど詳しく語りたいと思いますので、もし興味がある方は読んで頂けると幸いです。そして、僅か一ヶ月ほどで作ったのでショボい作りにはなっていますが、是非一度使っていただけると嬉しいです。
作った理由
ある一枚の画像
このサービスを作るきっかけになったのはある一枚の画像です。
この画像は1998年に放送された『Serial experiments lain』というアニメのワンシーンです。
ネット上で顔の見えないアバターが好き勝手に意見を言い合っています。
このシーンを見たとき、現在SNS上で起こる炎上をうまく表現されていると感じました。
全く顔も表情も分からないユーザー同士が140字程度で意思疎通を図るなんて土台無理な話です。
元々SNSの炎上に対する嫌悪感があったので、この画像を見ながら「どうすれば炎上しないSNSを作れるだろうか」と考えていました。
そこで思い浮かんだのが「文章に感情を付ける」というアイデアでした。今のSNSには「感情」が足りない
現実とインターネットの最大の違い、それは「感情」が見えるかどうかだと思います。
例えば、現実世界で挨拶する時、私たちは相手の表情、声のトーン、雰囲気から、相手がどんな感情かを判断することができます。
一方、インターネットの中では、どんな気分でいたとしても「おはようございます」の一言で表現できてしまいます(絵文字や顔文字が付く場合もありますが)。
これでは相手の気持ち、感情を全く理解することができません。
また、現在のSNSは構造上、どうしても自己顕示欲に塗れた人たちが多くなってしまうので、結果的に相手の意見を理解しようともせず自分の考えを押し付けるユーザーが発生してしまいます。
それがSNSで炎上が起こる原因だと感じました。
もし、ネット世界で相手の感情を簡単に理解できるようになれば、ネット上のコミュニケーションはどう変化するだろうか。
いつしかそんなことに頭が支配され始めました。「感情」を健康にしたい
これはサービスを作り終わった後に思い付いたことです。
みんなジムに行ったり、ジョギングしたり、自分の身体を痛めつけることで健康を維持(確認)していますが、一週間に一回自分の感情を確認することは怠っています。
しかし、感情を確認することは非常に重要です。
自分がどんな時に感情を変化させるのか、最近の自分の感情はどんな割合なのか。
それを徹底的に理解しなければ、真の意味で健康にはなれないのではないでしょうか。人の感情が知りたい
このサービスを作った最後の理由。
それは、「人の感情が知りたい」という単純な願望です。
私はある時期から、街中を歩いている一人一人が何を考えているのか、どんな感情で生きているのかと疑問に思って生きてきました。
この記事を読まれている方の中にも、そんな人がいると思います。
しかし、実際に街中の人に話しかけることもできず。
また、現状のSNSでは的確な感情把握ができません。
それなら自分で作るしかない、ということで「キドアイラク」を作ることを決めました。キドアイラクの三つの機能
ここからは「キドアイラク」の主な機能について説明します。
自分の文章に感情をつける
本サービスでは文章を投稿する際に「喜怒哀楽」の四つの感情をつけていただきます。
投稿された文章には感情が表示されるので、その文章がどんな感情で書かれたのか、一目でわかります。
また、文章を投稿するたびに自分の感情と向き合うことで、感情を俯瞰的に見る習慣がつき、結果的に自分の感情をコントロールしやすくなると考えています。
他にも、喜怒哀楽それぞれの投稿を見ることができるので、あまりネガティヴな意見を見たくない場合は、「よろこび」や「たのしい」の部分だけ見ていただくことも可能です。自分の感情がグラフ化される
マイページでは、最近自分がどんな気持ちでいるかを把握できる「感情グラフ」を見ることができます。
グラフは「当日」と「過去一週間」の二種類存在しており、他ユーザーの感情を見ることも可能です。
「怒りの感情が多いから減らそう」「もっと嬉しい気持ちを増やしたい!」といったように、日頃の感情を知ることで、自分を変えるきっかけを作ることができるのです。
他にも特定のワードがどのような感情のもと書かれているかを検索できる機能もありますので、ぜひお好きなワードを調べてお楽しみください。承認欲求から解放される
他のSNSでは「他人から評価されたい」と考える自己承認欲求の強いユーザーが数多くいます。
その原因は、いいね数や(ツイッターで言う)リツイート数が表示されるからでしょう。
SNSに資本主義の要素を作ったことで、多くの人がその数字に囚われるようになってしまいました。
しかし、本来良質なコミュニケーションを築く上で、そういった数字を表示する機能は必要ありません。
現にインスタグラムはいいねの数を非表示にしましたし、ツイッターもいいね機能を失くす話が度々出ています。
そういったこともあり、キドアイラクでは「いいね機能」「シェア機能」「フォロー機能」を導入しないことで、必然的に承認欲求から解放される仕組みに設計しました。
誰かに認められようとするのではなく、常に自分と向き合い、成長しようと前を向き続ける向上心を持ちたい方にオススメのサービスです。まとめ
全く0の知識から作ったので、ひとまず完成させられたことにホッとしています。
しかし、それ以上に圧倒的な技術不足を痛感しました。
自分が思ったようにできないことも多く、直さなければいけないところは山ほど存在します。
デザインも他所から拝借したものも多くありますから、それも直す必要がありそうです。
何より、自分の頭にあるものを形にする難しさを嫌という程知りました。
ものづくりって大変ですね。最後にもう一度URLを貼っておきます。
ぜひ一週間ほど使ってみてください。
自分の感情と向き合い、自己分析してくだされば、このアプリの効果を実感していただけると思います。
https://kidoairaku2019.herokuapp.com/ここまで読んでくださった皆さん、本当にありがとうございました。
エラーがなんども出て大変な時もありましたが、今回の経験を糧に、さらに色んなものを作っていきたいと思います。
その時はまたよろしくお願いします。
- 投稿日:2020-02-07T19:14:58+09:00
簡単なアプリケーションを作ってみる
railsでは簡単にこんなことができる!
「Ruby on RailsとはRubyのフレームワークだ」と聞きますね!
rails を使うとWebアプリケーションがつくれますが、rails を勉強していて、本当に簡単に(魔法のように)、簡単な(簡易的な)アプリケーションを作る方法を知りました。
それが、scaffoldジェネレータ
を利用した方法です。紹介したいと思います〜。scaffoldとは?
rails のアプリケーションでは、MVC(モデル、ビュー、コントローラー)を使って一つ一つ作成していき、ルーティングを設定しますが、そういうのをまとめて自動的に作ってくれるのが
scaffoldジェネレータ
なのですね。どんなときに使う?メリット・デメリットは?
(私の中では)
scaffoldジェネレータ
を使用するときは、このような時があげられます。
- アプリケーションをすばやく作りたい!
- アプリケーションを手っ取り早く作りたい!
- アプリケーションをかーんたんに作りたい!
- アプリケーションを試しに作りたい!
メリットはこちらです。
- 技術力なくてもやってみたら作れる
- アプリケーションの雛形となる部分を簡単に作成できる
- 開発が効率的に進む
- なので、とても便利!
- rails の大まかな概要がある程度わかる
もちろんデメリットもあります。
- あやふやな知識のままでもサービスを作れてしまう
- なので、rails の深い理解が困難である
こんなのを作ってみる
ユーザーを作成し、投稿ができます。
ユーザーや投稿を、編集・削除できます。アプリケーションの骨組みを作成する
ターミナルでお好きなディレクトリに、下のコマンドを実行し、アプリケーションの骨組みを作成します。
$ rails new greeting_app $ cd greeting_appユーザーモデルを作る
アプリケーションのユーザーで使うモデルを作成します。
文字列にはstring
を、整数にはinteger
という型を使います!
integer
型のidは、重複のないキーを割り当てられます。
カラム名 型 id integer name string string Usersリソースを
scaffoldジェネレータ
で生成します。
scaffold
の引数には、リソース名を単数形にしたもの(user)にします。
データモデルの属性も一緒に追加します。
(idカラムはrailsによって自動的に自動的に追加されます!)$ rails generate scaffold User name:string email:stringマイグレーションという1つのファイルが生成されました!(↓)
エディタで見ると、ファイル名の先頭には生成された時間が追加されているのがわかります。
そして、さっきのコマンドではオプションを追加していないt.timestamps
が作られています。
これは、created_at
とupdated_at
という2つのカラムを作成してくれます。db/migrate/[timestamp]_create_users.rbclass CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.string :name t.string :email t.timestamps end end end次のコマンドで、データベースにテーブルを作ります。
$ rails db:migrateブラウザで見る
生成されたページをブラウザで見てみましょう!
別のターミナルでgreeting_app
に移動し、ローカルサーバーを立ち上げます。$ rails serverhttp://localhost:3000/ をブラウザで開きます。
このような画面になっているとOKですね!
?「わーい! Railsを使用しています!」って書いてます。
http://localhost:3000/users を開いて、ユーザー一覧を見てみましょう!
/users
をつけると、insexアクション(ユーザー一覧)が呼び出されます。まだユーザーは1人もつくられていないので、「New User」リンクを押し、「Name」「Email」を入力、「Create User」ボタンを押して作ってみましょう!作れました!
※ちなみに、ユーザーをCreateした直後に画面上にでる緑の文字「User was successfully created.」は
flash
という機能を使っています!
画面にリンクが色々あるのでなんとなく分かると思いますが、この時点でユーザーの編集も削除もできますね!
ユーザーに関するページ
ページごとにURLも作られています。
URL アクション ページ内容 /users index すべてのユーザーを一覧するページ /users/1 show idが1のユーザーを表示するページ /users/new new 新規ユーザーを作成するページ /users/1/edit edit id=1のユーザーを編集するページ URLとアクションの組み合わせを変更する
今のままでは、
/
にアクセスしたときに「わーい! Railsを使用しています!」のままになっていて、/users
まで入力しないとアプリケーションを開けません。
そこで、ルーティングを変更してみましょう!(3行目を追加します。)config/routes.rbRails.application.routes.draw do resources :users root 'users#index' endこれで、「わーい! Railsを使用しています!」の代わりに、indexアクションが呼び出されることになります!
※scaffoldで生成されたユーザーコントローラー内のアクションは、
app/controllers/users_controller.rb
で確認することができます。ここを深く見てみるとどういうふうにページを表示しているかが見れて面白いですね〜。つづくよ
ポストモデルも
scafoold
ジェネレータを利用して作っていきたいのですが、長くなってしまったので、次か、次の次かの記事に書こうと思います!てげっててすみません。
↓こちら参考にしました?
scaffoldを利用した開発(1)
scaffoldを利用した開発(2)
rails tutorial 「魔法のように」というのは、rails tutorial で使われていた言葉でした!
- 投稿日:2020-02-07T17:39:44+09:00
ECS × ECR × Circle CiでRailsアプリケーションをデプロイ
前書き
・ECSのクラスターは起動タイプにFargateとEC2がありますが、今回は使い慣れている
EC2
を使います。
・本記事はAWSの環境構築は全てマネジメントコンソール
で行ってます。
(Terraformで1発でやりたいような人は他の記事を見るか、一応GitHubにTerraformでコード化もしているのでそちらを参考に)
・docker-composeは以下のような構成です(Nginxのコンテナ、Railsのコンテナ、Mysqlのコンテナ)本記事で目指したいデプロイ構成
(ECSのクラスターによって束ねられているEC2インスタンスや、VPC、RDS等は省略)
下準備
こちらからリポジトリをcloneしてください。
各Dockerfileと設定ファイルを用意しています。$ git clone https://github.com/s14228so/ECS-Rails6.git $ cd ECS-Rails6 $ docker-compose run app rails new . --force --database=mysql --api$ vi config/database.ymlconfig/database.ymldefault: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password #編集 host: db #編集 # ...省略 production: <<: *default database: <%= ENV['DB_DATABASE'] %> adapter: mysql2 encoding: utf8mb4 charset: utf8mb4 collation: utf8mb4_general_ci host: <%= ENV['DB_HOST'] %> username: <%= ENV['DB_USERNAME'] %> password: <%= ENV['DB_PASSWORD'] %>本番環境用の環境変数は後ほど
ECSのタスク定義
にて設定します。Rails6から必要なそうなので追加します。(同じlocalhostなら問題ない気がするんですが、これがないとnginx(localhost:80)にアクセスするときにエラーが起きてしまいました。。わかる人いたら教えてください)
config/environments/development.rbRails.application.configure do config.hosts.clear #追加$ cp docker/rails/puma.rb config/ (pumaの設定を上書き) $ mkdir -p tmp/sockets (socketファイルの置き場所を確保) $ docker-compose up -d --build $ docker-compose run app rails db:createhttp://localhost
にアクセスするとRailsのデフォルト画面が表示されるはずです。
localhost(:80)にアクセスするとnginxのwebサーバに(裏ではnginxがpumaにリクエストしている)
localhost:3000にアクセスするとpumaのアプリケーションサーバにリクエストを投げていることになります。scaffoldでjsonを返す簡易apiを作成します。
$ docker-compose run app rails g scaffold Post title:string $ docker-compose run app rails db:migrateseeds.rb5.times.each do |i| Post.create(title: "test#{i + 1}") end$ docker-compose run app rails db:seed下の画像のようにjsonが返ってきてればOKです!
ECRへのpush
AWSのマネジメントコンソールを開きます
ECRと検索します。
RailsとNginxのイメージ用のリポジトリをそれぞれ作成します。まずはrailsのイメージから作成します。
リポジトリ名にはrails-apiを(任意のリポジトリ名で問題ありません)
1つ目のコマンドで
aws command not found
と言われる場合は
aws-cliが入っていいないはずなので、$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" $ unzip awscli-bundle.zip $ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/awsでaws-cliをインストールしましょう。
4つのコマンドが表示されるので一つずつターミナルで入力しましょう。
※2番目のbuild時に以下のように-fでDockerfileのコンテキストを変えることに注意してください。
$ docker build -t rails-api -f ./docker/rails/Dockerfile .4つのコマンドが打ち終わるとECRのリポジトリにpushされていることを確認しましょう。
同様にnginxのDockerイメージも、ECRにリポジトリを作成してpushします。
$ docker build -t nginx -f ./docker/nginx/Dockerfile .VPCの作成
まずはEIPを作ります。
VPCから左側のElastic IPタブをクリック
新しいアドレスの割り当てをクリック => Amazon プール**を選択 => **割り当て左上のVPCダッシュボードをクリック => VPCウィザードの起動 => パブリックとプライベート サブネットを持つ VPCを選択
RDSを作成する際にVPCが複数のAZで構成されている必要があるので
パブリックとプライベートサブネットそれぞれを1cのAZにも追加します。サブネットのタブをクリック => サブネットの作成
public-1aサブネットのIPv4のアドレス指定動作を変更します。
[パブリック IPv4 アドレスの自動割り当てを有効にする] チェックボックスをオンにし、[Save (保存)] を選択します。先ほど後から追加したpublic-1cですがデフォルトでは、プライベートルートテーブルが選択されるので。
public-1aのものと同じルートテーブルになるように修正します。public-1cを選択した状態でアクション => ルートテーブルの編集をクリック
public-1aのルートテーブルのIDと同じルートテーブルのIDを選択して保存します。
RDSの作成
エンジンのオプションでMySQLを選択
テンプレート => 無料枠=>VPCで先ほど作成したVPCを選択
データベースの作成をクリック!
ECSでタスクの作成
マネジメントコンソールからECSを検索
左タブのタスク定義を選択 => 新しいタスク定義の作成をクリック
起動タイプの互換性: EC2を選択して次へ
タスク定義名に任意の名前を入力します。
ネットワークモードにbridgeを選択一番下の方までスクロールしていくとボリュームの追加という項目があります。
・ボリュームの追加を選択
ここでスコープをsharedに指定する
There is already a server bound to: <socket>
あとで怒られてしまいます。task
にするように注意してください中間の方まで戻リます。
タスクサイズは両方512を設定します。
**コンテナの追加というボタンがあるのでクリック
ここでnginx*とrails*のコンテナをそれぞれ追加していきます。まずはnginxのコンテナから。
コンテナ名はnginx
イメージにECRリポジトリに登録してあるnginxイメージのURIをコピペします。
ポートマッピングにはホストを0、コンテナポートを80に設定します。マウントポイントで先ほど作成したsocketsボリュームをマウントします。
また、Cloud Watch Logsにログを吐き出したいのでログ設定にチェックします他はとりあえず全て空欄でokです!
次にrailsのコンテナを作成します。
先ほどと同様にイメージにECRのrailsイメージのURIをコピペし、ボリュームマウントにsocketsを指定し(パスも同様に/app/tmp/sockets)、ログ設定にもチェックをいれましょう。
ポートマッピング: ホストを0、コンテナポートを3000
また、起動時のコマンドを追加します。作業ディレクトリは/appで。
bundle,exec,puma,-C,config/puma.rb
環境変数を追加します。
DB_HOST: RDSのエンドポイント
DB_DATABASE: RDSのDB識別子
RAILS_MASTER_KEY: ローカルのconfig/master.keyの値を貼り付けます。右下の作成ボタンをクリック!
ローダバランサーの作成
マネジメントコンソールからEC2を検索 => 左タブのロードバランサーを選択
=> ロードバランサーの作成名前を適当に入力してAZの設定を行います。
今回は上で作成したVPCを選択し、パブリックサブネットのみ(public-1a、public-1c)を追加します。
・セキュリティグループの設定
新しくセキュリティグループを作成します。・手順 5: ターゲットの登録
ECSの設定で登録するのでここではターゲットは登録せずに「次の手順:確認」をクリック作成!
ECSでクラスタの作成
ステップ1:クラスターテンプレートの選択
EC2 Linux + ネットワーキング
を選択ステップ2:クラスターの設定
EC2 インスタンスタイプにはm3.medium
を指定
キーペア: EC2インスタンスに接続するキーペアを指定します。
セキュリティグループは新規作成
します。
後ほど、ここで新規作成したセキュリティグループを用いて、ECSによって起動するEC2インスタンス、RDS、ALBなどを全て繋ぎ合わせます。作成をクリック!
クラスターを作成した時点でコンテナインスタンス(今回は2台)が立ち上がります。
サービスの作成
クラスター一覧で先ほど作成したクラスターを選択します。
サービスという項目に作成ボタンがあるのでそちらをクリックしますステップ 1: サービスの設定
タスク定義に作成済みのタスクを指定
クラスターに作成済みのクラスターを指定
サービス名に任意の名前を入力サービス対応はレプリカを、
タスクの数は2を設定します。ECSで言うタスクはコンテナを意味します。
レプリカはクラスター全体で必要なコンテナ数を指定してそれを維持します。
デーモンでは、各コンテナインスタンスにコンテナのコピーを1つ配置し維持します。他は変更せずに次のステップへ
ステップ 2: ネットワーク構成
ロードバランシングでApplication Load Balancerにチェックをいれます。サービスの検出の統合の有効化のチェックを外します。
ステップ 3: Auto Scaling (オプション)
・今回はサービスの必要数を直接調整しないをチェックして次のステップへサービスの作成をクリック!
このサービスの作成で、これまで作成してきたクラスタとタスク、ALBを全て繋ぎ合わせることができました。
セキュリティグループの設定
ここが重要です!
今まで作成してきたコンポーネント間のトラフィックを許可するためにECSのクラスター作成時に一緒に新規作成したセキュリティグループのインバウンドを以下のように修正します。また、EC2インスタンスからRDSにアクセスできるようにします。
[サービス]タブで、RDSを検索してクリック => 左側のメニューで、「データベース」をクリック。
次に、作成したデータベースを見つけてクリック => 下のタブでセキュリティグループをクリック以下のようにインバウンドを編集します。
EC2インスタンスにSSHログイン
IPv4 パブリック IPをコピーしておきます。
ターミナルを開きます。
$ ssh -i [キーペアのpath] ec2-user@[パブリック IP]$ docker psとするとコンテナが立ち上がっていることがわかります。
ちなみにdocker imagesとするとECRに登録してあるイメージが出てきます。Railsのコンテナに入ってデータベースを作成しましょう。
$ docker exec -it [RailsコンテナのID] /bin/bash$ echo $DB_DATABASEとするとタスク定義の際に設定した環境変数の値が出力されているはずです。
環境変数でRAILS_ENVにproductionが設定されているのでRAILS_ENV=productionとかしなくでも大丈夫です。$ rails db:create $ rails db:migrate $ rails db:seed[ALBのDNS名]/postsにアクセスして以下のようにjsonが返ってきていれば大成功です!!!
※基本的にコンテナのログは
Cloud Watch Logs
に吐き出されているのでそちらを見ればデバッグできると思います。Circle Ciでの自動デプロイ化
記事が長くなってきたので、config.ymlの説明は省略します。
公式を参考に!
ECR: https://circleci.com/orbs/registry/orb/circleci/aws-ecr
ECS: https://circleci.com/orbs/registry/orb/circleci/aws-ecs?version=0.0.15AWS_ECR_ACCOUNT_URLとか大文字になっているものは環境変数なのでCircle Ciのプロジェクト設定の
Environment Variables
で設定しておく必要があります。version: 2.1 orbs: aws-ecr: circleci/aws-ecr@6.7.0 aws-ecs: circleci/aws-ecs@1.1.0 workflows: # Nginxのデプロイ nginx-deploy: jobs: - aws-ecr/build-and-push-image: account-url: AWS_ECR_ACCOUNT_URL region: AWS_REGION aws-access-key-id: AWS_ACCESS_KEY_ID aws-secret-access-key: AWS_SECRET_ACCESS_KEY create-repo: true dockerfile: ./docker/nginx/Dockerfile repo: nginx tag: "${CIRCLE_SHA1}" filters: branches: only: master - aws-ecs/deploy-service-update: requires: - aws-ecr/build-and-push-image family: 'nginx-rails-app' # ECSのタスク定義名 cluster-name: '${ECS_ARN}' #ECSのクラスターのARN service-name: 'test' #サービス名 container-image-name-updates: "container=nginx,tag=${CIRCLE_SHA1}" # Railsのデプロイ rails-deploy: jobs: - aws-ecr/build-and-push-image: account-url: AWS_ECR_ACCOUNT_URL region: AWS_REGION aws-access-key-id: AWS_ACCESS_KEY_ID aws-secret-access-key: AWS_SECRET_ACCESS_KEY create-repo: true dockerfile: ./docker/rails/Dockerfile repo: rails tag: "${CIRCLE_SHA1}" filters: branches: only: master - aws-ecs/deploy-service-update: requires: - aws-ecr/build-and-push-image family: 'nginx-rails-app' # ECSのタスク定義名 cluster-name: '${ECS_ARN}' #ECSのクラスターのARN service-name: 'test' #サービス名 container-image-name-updates: "container=rails,tag=${CIRCLE_SHA1}" #AWS_ECR_ACCOUNT_URL => ${アカウントID}.dkr.ecr.${リージョン}.amazonaws.com
- 投稿日:2020-02-07T17:24:05+09:00
【実体験をもとに】30歳未経験から独学4ヶ月でバックエンドエンジニアとしてWeb系自社開発企業へ転職するまでのロードマップ
こんにちは。
2020年2月現在、スタートアップ期のWeb系自社開発企業から内定をいただきました。
今回はこれからプログラマーとしてWeb企業へ転職される方を応援するため、私が知識ゼロの状態から学習をスタートし転職するまでの過程を踏まえたロードマップを共有します。
一つの例として参考にしていただければと幸いです。前置き
本記事はプログラミング初心者を対象にしたものなので、理解しやすいように噛み砕いて文章を作成しています。
多少語弊のある内容もあるため現役プログラマーの方の閲覧時は生暖かい目で見てください(笑)私の実体験をもとに作成していたため、実際にはもっと素晴らしいロードマップもあると思います。
投稿者スペック
エンジニアキャリア1ヶ月目のできたてホヤホヤ新人
年齢:30歳(既婚)
住所:埼玉県
前職:一般企業の拠点マネジメント系
学歴:大卒(文系)
・プログラミングの知識はゼロ(多少Excelを触れるくらい)
・わりとコミュ力はあるほう転職先での待遇
給料(年収):400万ほど(前職と同程度)
社会保険などの福利厚生
リモートワーク可学習開始から転職までにかかった期間
■4ヶ月
うち3ヶ月は前職と並行して学習
うち1ヶ月は前職の有給を使用し就活に専念
前職の退職日1週間後に内定をいただきました。学習方法
eラーニング(Progade.CODEPREP)
MENTA
Qiita
その他IT技術に関するブログ
各技術の公式リファレンス(各技術公式の説明書)転職完了時のスキルセット
HTML
CSS
Ruby
Ruby on Rails
MySQL
Rspec
AWS
Docker
CircleCI
Gitロードマップ(1月スタートとする)
1月:基本学習(Progateを使用)
2月:ポートフォリオ作成
3月:ポートフォリオのブラッシュアップ
4月:就活私は仕事をしながら通勤時や帰宅後、休日を利用して学習しました。
仕事の繁忙から半月の間全く勉強できない事も・・・。
平日は1〜3時間、休日は4〜7時間ほど勉強していました。
(もちろん30分くらいしか勉強しなかった日も間々ありました)
もっと少なくても多分ダイジョーブ!先に記載しますが、Progateなどの学習サイトを周回する必要は無いと思っています
実際に技術を使用して何か成果物を作るのが一番早い学習方法であり、学習サイトではそのための足がかりさえ得られれば良い。というのが私の個人的見解。(百聞は一見に如かずというやつですね)
たっぷりと時間があるならともかく、仕事をしながら勉強していた私にとって学習サイトを周回するのは時間的な費用対効果が低かったのです。1月 基本学習
第1週 HTML&CSSの学習
Progate (https://prog-8.com/) を利用しての学習。
難しいものではありません。サクッとクリアして、何か簡単なWebサイト1つを模写しました。
私は下記のようにデザイン例の載ったサイトから好みのものを一つ選んで同じようなレイアウトを1から作ってみました。
https://sankoudesign.com/
※「カーソルを合わせたらポップアップが出る〜」だとかそういった事はスルーして良いと思います。第2週 Rubyの学習
Progateを利用しての学習。
完全に理解する必要は無いと思います。この段階では感触さえつかめれば良。
基礎の基礎とはいえ、この段階で完全な理解をするのは難しく時間がかかります(=挫折しやすくなる)。
あまり気構えせずにユルく馴染ませていきましょう。
※逆にこの段階では、学んだことを何に使うのか分かっていない状態のため、うまく定着しないでしょうしね(^^;)
※先述したように今後のことを考えるとさらに踏み込んだ学習は必須なので、後で改めて学習しましょう。第3週〜第4週 Ruby on Rails の学習
Progateを利用しての学習。
今までと違いしっかりと理解しながら学習すべきだと思いました。
1つのセクションが終わるたび自分のPC上で同じように開発を行ってゆくという方法で復習をしました。
Progateでは「指示された通りに穴埋めをしてゆく」というスタイルで課題を進めるため、ただの作業になってしまいがち。「今自分が何をしているのか」ということや「システムの全体像」がイメージしづらく、うまく定着しないと考えたからです。2月 ポートフォリオ作成
プログラマー転職において必須とも言えるのがポートフォリオの作成です。
これに最低限のクオリティを持たせなければ好条件での転職は望めないでしょう。
※どのようなポートフォリオを作成すべきかについてはまた別の機会に提案できればと思っています。第1週〜第2週 基本機能を備えた動画投稿サービスを作成 & MySQLの学習
Qiitaを参考にした記事投稿サービスを作成しました。
同時に否が応でもDBに関する学習をしなければなりません。MySQLあるいはPostgreSQLを選択するのが無難かなと。
着実に機能を実装してゆくのはとても楽しく苦にならないかと思いますが、これまでとは違い予期せぬエラーとの戦いが始まります。
解決できないエラーに直面した時に相談できる相手がいると良いですね。
slackなどのプログラマーコミュニティーに入ったり、MENTAを利用することをお勧めします。
また、ここからGitHubの使用を始めました。(1時間もあれば使えるようになります)第3週〜第4週 作成したアプリをAWSへデプロイ
Herokuへのデプロイであればすぐに完了すると聞きますが、ここはより実践的にAWSへデプロイしました。
初学者にはかなりの難題でした。私は先輩エンジニアに教えてもらってなんとかなりましたが、知り合いがいない場合はMENTAの使用を強くお勧めします。3月 ポートフォリオのブラッシュアップ
ここまでで作成したポートフォリオはチュートリアルで学んだものに毛が生えた程度のものという評価になると考え、成果物に対してさらに+αのアピールポイントをつけていきました。
またこの時期は年末で私の仕事が大変忙しく、学習にかけられる時間は半分以下になっています。第1週〜第2週 Dockerによる開発環境構築
Dockerは初学者には大きなハードルとなりますが、現在の開発現場ではスタンダードになっているとの情報を得ましたので必ず手をつけることをお勧めします。
前職場の先輩がベテランプログラマーの知人に私のことを話した際「Dockerを使用してポーロフォリオを開発しAWSへデプロイした」と伝えたところ「それは就活成功するやつだね」と言われたそうです。
そのくらい「Dockerを扱える」というのは初学者への評価をするにあたって一つの指標となるのかなと思いました。参考にしたのはQiitaの記事https://qiita.com/nsy_13/items/9fbc929f173984c30b5d
Dockerは注目度が高い技術のため、参考文献が多いのが幸いですね!先人に感謝!!第3週〜第4週 CircleCIの導入 & Rspec導入
※私自身は仕事で忙しくこの時期は全くと言っていいほど学習に手をつけられていません。しかし、本来であればこのタイミングが良いと思い記載します。
CIツールとしてCircleCiを学習。これもまた注目度の高い技術なので参考文献がゴロゴロ転がっています。
CD機能についてまではできていなくても良いと思います。この段階では自動テストのために導入すれば十分かと。
CDまでできたらすごい。ぜひ教えてください。【補足】 ここでCircleCIでなく、何かしらのAPIをポートフォリオに導入する方が就活に活きると思いました。
4月 就活
いよいよ就活です。
就活と同時並行で改めてRubyの学習を行うとなお良かったな〜と思います。
就活における注意点というか心構えのようなものは別の機会でお話しできればと思いますが、私が強く思ったことだけ。
- 焦らずゆとりを持って取り組む。
- ただし最初の1社はとにかく早い段階で選考を受ける。
- 何十社も受ける必要はない。
- Wantedlyプレミアム会員に登録する。
5月まで突入しても良いと思います。そうそううまくいくものではないので、納得いく会社から内定をもらえるまでじっくりと取り組んでください。
【補足】3月の段階から就活をスタートする方が効率的かもしれません。
私は仕事が忙しく、とても無理でしたが・・・。
終わり
以上が私がプログラミング学習を始めて〜内定に至るまでの過程です。
長文を読んでいただきありがとうございます。
最後に私のプログラマー転職を成功に導いてくれた要因を列挙します。
- コツコツと勉強を続けていく持続力
- 「プログラミング楽しい!」とまでは行かないまでも、特に苦にならないという相性。
- 初対面の人とも仲良くなれるコミュニケーション能力。
- 即行動・即実践する意識。
- アドバイスをしてくれるエンジニア仲間。
- ほどほどに休憩を取っていたこと。
- 無職状態になったとしても生活できるだけの貯金があったこと。
- くじけそうな時に支えてくれた家族。
- 投稿日:2020-02-07T17:01:40+09:00
Railsでja.ymlが反映されない
railsにてja.ymlに追記をしたが反映されなかった
ja.yml#変更前(反映されなかったもの) ja: activerecord: attributes: board: name: 名前 title: タイトル body: 本文 #変更後 ja: activerecord: attributes: board: name: 名前 title: タイトル body: 本文boardのインデントが問題で反映されなかったよう。
直したら反映された。
- 投稿日:2020-02-07T14:56:48+09:00
【Rails,Ajax】$.ajaxのurlについて
やりたいこと
画面に値を入力し、非同期通信でtodos_controllerのcreateメソッドへ送り、登録処理を行う。
疑問
$.ajax内のurlに「/todos.json」を設定しているが、なんでcreateメソッドが呼び出されるの?
createへ行くには「/todos」を指定すべきじゃないの?$.ajax({ type: 'POST', url: '/todos.json', data: { todo: { content: todo } }, dataType: 'json' })Prefix Verb URI Pattern Controller#Action todos POST /todos(.:format) todos#createわかったこと
(.:format) によって、「/todos.json」のような拡張子の指定もできるらしい。
よって上記url指定でもcreateメソッドが呼び出される。ちなみにurlを「/todos」にしても正常に動作しました。
(今回は教材に従って「○○.json」にしたけど、ルールとかあるのかしら)
- 投稿日:2020-02-07T13:44:28+09:00
Rails コーティング規約について 2
はじめに
Ruby、Railsの基礎を学習中の方に向けて記載致します。
Rubyのコーティング規約はコチラをクリック願います。
Railsのコーティング規約 1 はコチラをクリック願います。
私自身これからチーム開発を行う上で大事にしたい。知っておきたいことをOutputします。ActiveRecord Queries
idを指定してひとつのレコードを取得する場合は、whereよりfindを使う。
qiita.rb# 悪い例 User.where(id: id).take # 良い例 User.find(id)複数の属性を指定してひとつのレコードを取得する場合は、whereよりfind_byを使う。
qiita.rb# 悪い例 User.where(first_name: 'Raiga', last_name: 'Yoshida').first # 良い例 User.find_by(first_name: 'Raiga', last_name: 'Yoshida'))さいごに
コーティング規約については毎日更新します。
皆様の復習等にご活用頂けますと幸いです。
- 投稿日:2020-02-07T12:48:16+09:00
RSpecのassignsメソッドを復習するぞ
assignsメソッドの使い方
assignsメソッドはコントローラのインスタンス変数をテストするメソッド。
引数にインスタンス変数をシンボル型で渡す。(超重要)categories_controller_spec.rbrequire 'rails_helper' RSpec.describe Potepan::CategoriesController, type: :controller do describe "GET #show" do let!(:taxon) { create(:taxon, name: "Bags") } before { get :show, params: { id: taxon.id } } it "assigns @taxon" do expect(assigns(:taxon)).to eq taxon end end endこの場合、コントローラ側で@taxonというインスタンス変数を定義していることになる。
テストの内容としては、コントローラで作成した@taxonというインスタンス変数とテスト内で作成したtaxonというテストデータが一致しているかを検証している。
- 投稿日:2020-02-07T10:19:46+09:00
【Rails】gem'RSpotify'を利用し、SpotifyAPIからアーティスト情報を取得する検索機能を作成する
概要
Railsアプリケーションにて、SpotifyAPIを利用し、検索機能を実装します。
SpotifyAPIのラッパーであるRSpotifyというgemを利用する方法になります。SpotifyAPIへアプリの登録
SpotifyAPIを利用するにはアカウントを作成し、デベロッパー用のダッシュボードで連携するアプリを登録する必要があります。
アプリを登録すればAPIへアクセスするためのIDが取得できます。ユーザーアカウントの登録を行う。
https://www.spotify.com/jp/アカウント作成完了後にデベロッパー用のダッシュボードへ。
https://developer.spotify.com/"CREATE AN APP"をクリック。
アプリケーション名とアプリケーションの説明を英語で記載し、
アプリの種類は何かをチェックしてください。
商用かどうかが確認されますので、いずれかを選択。
今回はNoを選択しました。作成完了すれば、
"CLIENT ID"と"CLIENT SECRET ID"が発行されます。
"CLIENT SECRET ID"は"SHOW CLIENT SECRET"をクリックすれば確認できますね。Rspotifyを用意する
今回はSpotify API のラッパーであるRSpotifyというgemを使って実装します。
ラッパーとは
プログラミングやソフトウェア開発の分野では、ソフトウェアやプログラム部品などが提供するクラスや関数、データ型などを本来とは異なる環境や方法で利用できるようにしたものをラッパーという。対象の種類に応じて「ラッパー関数」「ラッパークラス」「ラッパーライブラリ」などという。元の機能を包み、覆い隠す役割を果たすためにこのように呼ばれる。
ラッパーが作成・提供される理由は様々で、元のクラスなどがそのままでは利用できない別の環境で利用できるようにしたり、煩雑な仕様や設定などを隠蔽したり自動化したりしてシンプルな手順で利用できるようにしたり、別の機能を追加したりするのに使われる。
出典:IT用語辞典(http://e-words.jp/w/%E3%83%A9%E3%83%83%E3%83%91%E3%83%BC.html)
この辺の理解は合っているかわからないのですが、簡単にいうと元々の機能(今回はSpotifyAPI)のデータ参照ができるように仲介役であるラッパー(今回はRSpotify)を挟んであげるということだと認識します。
通常はRuby言語でSpotifyAPIのデータを参照することはできないのに、Rsporifyを使うことでRuby言語で参照できるようになるのです。
RSpotify導入方法
RSpotifyを導入していきます。
◆RSpotifyのGithub
https://github.com/guilhermesad/rspotifygem 'rspotify' gem 'dotenv-rails'$ bundle install.envファイルで環境変数を保管するために
'dotenv-rails’
も入れておきます。
今回はMusicモデル内に検索機能を加えていくとして書いていきます。RspotifyのREADMEに記載されている通り、
rspotify
を読み込むと、search
メソッドを使ってSpotifyAPIのデータを参照することができます。
READMEは'Arctic Monkeys'で検索した場合の例を記載してくれています。require 'rspotify' artists = RSpotify::Artist.search('Arctic Monkeys') arctic_monkeys = artists.first arctic_monkeys.popularity #=> 74 arctic_monkeys.genres #=> ["Alternative Pop/Rock", "Indie", ...] arctic_monkeys.top_tracks(:US) #=> (Track array) albums = arctic_monkeys.albums albums.first.name #=> "AM" am = albums.first am.release_date #=> "2013-09-10" am.images #=> (Image array) am.available_markets #=> ["AR", "BO", "BR", ...] tracks = am.tracks tracks.first.name #=> "Do I Wanna Know?" do_i_wanna_know = tracks.first do_i_wanna_know.duration_ms #=> 272386 do_i_wanna_know.track_number #=> 1 do_i_wanna_know.preview_url #=> "https://p.scdn.co/mp3-preview/<id>" playlists = RSpotify::Playlist.search('Indie') playlists.first.name #=> "The Indie Mix" # You can search within other types too albums = RSpotify::Album.search('The Wall') tracks = RSpotify::Track.search('Thriller')フォームにアーティスト名を入力して検索できるようにする
searchメソッドを利用して、自由にアーティスト名を検索できるように実装していきます。
musics_controller.rbclass MusicsController < ApplicationController require 'rspotify' RSpotify.authenticate(ENV['SPOTIFY_CLIENT_ID'], ENV['SPOTIFY_SECRET_ID']) def search @musics = Music.all if params[:search].present? @searchartists = RSpotify::Artist.search(params[:search]) end end
envファイルには初めに取得したIDを記載します。SPOTIFY_CLIENT_ID="自分のCLIENT ID" SPOTIFY_SECRET_ID="自分のCLIENT SECRET ID"
検索して受け取ったアーティスト情報から、アーティスト名とアーティスト写真を取得して表示させたいと思います。
viewディレクトリにsearch.html.erbファイルを作成して実装します。musics/search.html.erb<h3>アーティスト名で検索</h3> <%= form_with url: search_artist_boards_path, method: :get, local: true do |form| %> <%= form.text_field :search %> <%= form.submit 'アーティスト名検索', name: nil %> <% end %> <h1>検索結果</h1> <div> <% if @searchartists.present? %> <% @searchartists.each do |searchartist| %> <div> <h3><%= searchartist.name %></h3> <% if searchartist.images.any?%> <%image = searchartist.images[1]%> <%= image_tag(image["url"])%> <%else%> <%= image_tag("default.jpg")%> <%end%> </div>Searchアクションを呼び出し、アーティスト情報が取得できれば同じ画面にリダイレクトし、検索結果が表示されるようにしています。
method: :get,
を記述しないとpostが飛び、createアクションが呼び出されてしまいます。
"default.jpg"
はアーティスト写真が存在していなかった場合に表示させる用の画像です。
imagesディレクトリに保存して呼び出しています。
実際データはこんな感じで取得できます。
あいまい検索なので、2件該当しています。
@imagesはサイズが3種類あるため、中間のサイズを表示させるようにimages[1]としているわけです。[#<RSpotify::Artist:0x00007f8865cd5808 @followers={"href"=>nil, "total"=>8919915}, @genres=["garage rock", "modern rock", "permanent wave", "rock", "sheffield indie"], @images=[{"height"=>640, "url"=>"https://i.scdn.co/image/ed0552e9746ed2bbf04ae4bcb5525700ca31522d", "width"=>640}, {"height"=>320, "url"=>"https://i.scdn.co/image/b435e99aa7f1e27db56b6a4dc9df85e5636b22d6", "width"=>320}, {"height"=>160, "url"=>"https://i.scdn.co/image/73c4e49abed008fe0c5e4f1437b8b486c7670ecd", "width"=>160}], @name="Arctic Monkeys", @popularity=86, @top_tracks={}, @external_urls={"spotify"=>"https://open.spotify.com/artist/7Ln80lUS6He07XvHI8qqHH"}, @href="https://api.spotify.com/v1/artists/7Ln80lUS6He07XvHI8qqHH", @id="7Ln80lUS6He07XvHI8qqHH", @type="artist", @uri="spotify:artist:7Ln80lUS6He07XvHI8qqHH">, #<RSpotify::Artist:0x00007f8865cd5790 @followers={"href"=>nil, "total"=>177}, @genres=[], @images=[{"height"=>640, "url"=>"https://i.scdn.co/image/ab67616d0000b27388ccc49d173ca3f4c5ea5a82", "width"=>640}, {"height"=>300, "url"=>"https://i.scdn.co/image/ab67616d00001e0288ccc49d173ca3f4c5ea5a82", "width"=>300}, {"height"=>64, "url"=>"https://i.scdn.co/image/ab67616d0000485188ccc49d173ca3f4c5ea5a82", "width"=>64}], @name="Arctic Monkeys Tribute Band", @popularity=4, @top_tracks={}, @external_urls={"spotify"=>"https://open.spotify.com/artist/2hv9oBOxgWSFnZJPW6UL58"}, @href="https://api.spotify.com/v1/artists/2hv9oBOxgWSFnZJPW6UL58", @id="2hv9oBOxgWSFnZJPW6UL58", @type="artist", @uri="spotify:artist:2hv9oBOxgWSFnZJPW6UL58">]
Searchアクションはresourcesでは自動で生成されないので、新しく作成する必要があります。
MusicコントローラーでSearchアクションが呼び出せるように、ルーティング設定を行います。routes.rbRails.application.routes.draw do resources :musics do collection {get "search"} end end独自ルーティングを作成するのは
memberとcollectionの2つの方法がありますが、
memberの場合はroutingにidが必要になり、
Collectionの場合はidは不要になります。
今回は検索機能でid付与は不要ですのでcollectionでルーティング設定しています。これでアーティスト名を自由に検索できるようになりました!
RSpotifyを利用することでめちゃくちゃ簡単に実装できました。searchの方法含めて、色々なデータ取得の方法は公式リファレンスに記載があります。
https://developer.spotify.com/documentation/web-api/reference/albums/検索デモもできるので便利です。
- 投稿日:2020-02-07T01:57:53+09:00
rails チュートリアル2週目~ヘルスケアwebサービスを自分で作る医者の日記~
railsチュートリ
の3章初めからてこずった最初sqlite3 をsqlite とgemfileに書いて
失敗
その後 書き直して add commit heroku にpushするもデプロイできず
heroku run railsするも
Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError) herokuとなる。
herokuはsqlite3いらないんじゃなかったの?
bundle install --without production でsqlite3はのぞいているのにremote: ###### WARNING: remote: remote: Detecting rails configuration failed remote: set HEROKU_DEBUG_RAILS_RUNNER=1 to debug remote: remote: remote: ###### WARNING: remote: remote: No Procfile detected, using the default web server.が結局残ったがデプロイできた
誰がこの辺の理屈教えてください。
次回は3.2
あとgitの仕組みわからない
いい理解方法ないものか
- 投稿日:2020-02-07T01:16:49+09:00
RailsでmySQLを使ってgem:deviseを実装する
こんにちは
Railsでポートフォリオを作るときに、mySQLを使ってさらにdeviseを導入してログインなどのシステムを導入したい
そんな人たちに、自分が使ったやり方を自分の復習も込めて書きます。
まずは、データベースにmySQLを使っている、railsプロジェクトを作る
$rails new プロジェクト名 -d mysql
造られたプロジェクトのgemfileに
gem 'devise'
を記述する。
ここまで書いたら、下記のコマンドを実行して、gemファイルを読み込みます。
$bundle install
まずはここまでで一セット。そして、間髪入れず第二セットいきます。
gem:deviseの関係ファイルをプロジェクトに作ります。このとき、先ほどの作ったrailsプロジェクトのフォルダに移動しておいてください。
$ rails generate devise:install
上記のコマンドを実行すると下記のような文章が出てきます。
===============================================================================
Some setup you must do manually if you haven't yet:
Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
Ensure you have defined root_url to something in your config/routes.rb.
For example:root to: "home#index"
Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:<%= notice %>
<%= alert %>
If you are deploying on Heroku with Rails 3.2 only, you may want to set:
config.assets.initialize_on_precompile = false
On config/application.rb forcing your application to not access the DB
or load models when precompiling your assets.You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
上から順に説明すると
1、config/environments/development.rbにconfig.action_mailer.default_url_options = { host: 'localhost', port: 3000 }を記述してくれよな
2、config/routes.rbにroot to: "home#index"を記述してくれよな
3、app/views/layouts/application.html.erbに
<%= notice %>
<%= alert %>
を追記してくれよな4,使っているRailsのバージョンが3.2だったらconfig/application.rbに
config.assets.initialize_on_precompile = falseを記述してくれよな
(Railsのバージョンはrails -vでわかる)5,deviseにデフォルトで設定されている画面(view)をカスタマイズしたい時は、
rails g devise:views
を実行すると変更を加えるためのviewファイルを作成するぞという意味です。
これで、第二セットは終わり。ラストにデータベースを作って終わります。
mySQLを
$sudo service mysqld start
で立ち上げてから
下記のコマンドでデータベースを作る
rake db:create
そして、モデル(今回はUserモデルを作る)
$ rails g devise user
gem 'devise'のおかげでemailとpasswordはこのコマンドを使うと自動で追加されるらしい
追加したいカラムは都度追加すれば良い
また、このままではコントローラーがdeviseになっているため
userコントローラーで操作できるようにするため、下記のソースをroute.rbに記述する
devise_for :users, controllers: {
registrations: 'users/registrations',
sessions: 'users/sessions',
passwords: 'users/passwords'
}その後、userコントローラーを作る,
認証ユーザーのモデルが User であれば、app/controllers/users ディレクトリ以下にファイル作成
$rails g devise:controllers users
そして、この設定をデータベースに反映させる
rake db:migrate
以上です。
- 投稿日:2020-02-07T00:25:11+09:00
コード書いたことないPdMやPOに捧ぐ、Rails on Dockerハンズオン vol.3 - Scaffold, RESTful, MVC -
この記事はなにか?
この記事は私が社内のプログラミング未経験者、ビギナー向けに開催しているRuby on Rails on Dockerハンズオンの内容をまとめたものです。ていうかこの記事を基にそのままハンズオンします。ハンズオンは
1回の内容は喋りながらやると大体40~50分くらいになっています。お昼休みに有志でやっているからです。
現在進行形なので週1ペースで記事投稿していけるように頑張ります。
ビギナーの方のお役にたったり、同じように有志のハンズオンをしようとしている人の参考になれば幸いです。
他のハンズオンへのリンク
・ Vol.1 - Introduction -
・ Vol.2 - Hello, Rails on Docker -
・ Vol.3 - Scaffold, RESTful, MVC -
$
,#
,>
について
$
: ローカルでコマンドを実行するときは、頭に$
をつけています。
#
: コンテナの中でコマンドを実行するときは、頭に#
をつけています。
>
: Rails console内でコマンド(Rubyプログラム)を実行するときは、頭に>
をつけています。
はじめに
第三回目の今回は、Railsの便利機能を使って簡単なWebアプリケーションを作ってみようと思います。
また、Railsアプリでとても大切な『RESTful』や『MVC』について紹介していきます。ScaffoldでRailsアプリを作ってみる
ScaffoldはRailsの強力な機能の一つで、数コマンドでRails appを作成することができます。
一方で、数コマンドであまりにも多くのことがなされてしまうので勉強する上では頭が混乱してしまうかもしれません。
ただ、Railsアプリの基本がつまったものですので、一度触ってみましょう!User管理アプリを作る
Scaffoldを使って、Userを管理するアプリを作ってみます。
まず、webコンテナを立ち上げて、コンテナ内に入って操作していきましょう。$ docker-compose up -d $ docker-compose exec web ash
docker-compose exec <service> <command>
は<service>
で<command>
を実行するコマンドです。ash
はalpine linuxのシェルです。シェルというとbash
やzsh
などが思い浮かぶと思いますが、alpine linuxではash
です。これでコンテナの中に入れたかと思います。今までローカルでコマンドを実行するときは
$
を頭につけていましたが、コンテナ内でコマンドを実行するときは#
をつけるようにします。#
がついている場合は、上のコマンドを実行してコンテナ内に入っていると思ってください。何も言わずに以下のコマンドを実行してみましょう。
# rails generate scaffold user name:string email:string # rails db:migrateこれだけですでに以下のようなアプリができています。 http://localhost:3000/users にアクセスしてみて確かめてみてください。↓のようなアプリが出来上がっているはずです。
色々と触ってみてください。たった2コマンドでこのアプリができちゃうの強すぎませんか?笑ではまずコマンドの説明をしておきます。
rails generate scaffold model_name [field:type...field:type]
rails generate scaffold
はScaffoldでRailsアプリを作成するコマンドです。generate
はg
と省略できます。ちなみにScaffoldは『足場』と和訳されます。Scaffoldは、1つのModelに対してRESTful(後述)なWebアプリケーションを作成します。
model_name
にはそのModelの名前を入力します。慣習的にModelの名前は単数形を用います。
さらにfield
(属性)とtype
(型)を定義します。この組み合わせは複数定義できます。このコマンドを叩くだけで、そのModelの生成だけでなくRESTfulなアプリケーションに必要な全てのファイルが生成されるわけです。
具体的にはこの後で説明していきます。rails db:migrate
rails generate scaffold
だけで必要なファイルは生成されているのですが、Databaseへの反映(Tableの作成)がまだできていません。
rails db:migrate
はマイグレーションファイルと呼ばれるファイルの内容に沿ってDatabaseを操作するためのコマンドです。先ほどの
rails generate scaffold
で作成されたファイルの中にマイグレーションファイルも含まれています。マイグレーションファイルはrails generate scaffold
で定義したfield:type
に合わせて生成されています。(マイグレーションファイルは次回のハンズオンで触れます)さて、Scaffoldで作成したRailsアプリを色々と触っていただいたかと思いますが、Railsアプリには重要な考え方やアーキテクチャとして『RESTful』と『MVC』があります。これらについて紹介しますね。
RESTful
RESTという言葉をご存知でしょうか?よくREST APIとか言われますよね。
RESTは『REpresentational State Transfer』の略で、『Fielding Dissertation: CHAPTER 5: Representational State Transfer (REST)』で言及されています。Wikipediaによると以下の設計原則を持っています。
- ステートレスなクライアント/サーバプロトコル
- すべての情報(リソース)に適用できる「よく定義された操作」のセット
- リソースを一意に識別する「汎用的な構文」
- アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
少し表現が難しいっすね。これはあくまでAPIで用いられる設計原則なのですが、RailsはこのRESTの原則にそってシステムを作れるということで
RESTful
と表現されますね。1. ステートレスなクライアント/サーバプロトコル
基本的にステートレスです。サーバー側でクライアントとのステート(状態)を管理せず、同じリクエストであれば同じ結果がいつでも返ってくるように設計することでステート管理の煩わしさをなくしています。
2. すべての情報(リソース)に適用できる「よく定義された操作」のセット
リソースに操作が定義されている...
RESTではROA
(Resource Oriented Architecture)を原則としています。リソースを中心に考えるとそれに対する操作とはいわゆるCRUD
(Create/Read/Update/Delete
)であるといえます。REST APIではHTTPメソッドのPOST/GET/PATCH(PUT)/DELETE
をそれに対応させて定義しています。
RailsでもROAを原則としてアプリを設計していくことが理想です。3. リソースを一意に識別する「汎用的な構文」
汎用的な構文...なんだこれもうわかりにくくないだろうか。
これは、例えばユーザーモデルであれば/users
のパスで操作ができる、商品モデルなら/purchases
のパスで操作できる、って感じです。4. アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
もうなんともですね。笑
これはHTTP
とか使いましょう。って話です。まとめると以下のような図になると思ってます。
このように、「URL」で「リソース」を指定し「HTTPメソッド」で「操作(CRUD)」を指定するイメージですね。
大切な考え方として「リソース」が主軸にあるということを抑えましょう。先ほどScaffoldで生成したアプリケーションをみてみても
User
モデルを作成して、参照して、更新して、削除する、アプリケーションでした。アプリケーションを考える上でも、このRESTfulを念頭におきながらアーキテクトするとRailsで超絶作りやすくなりますね。MVC
MVC
はModel
、View
、Controller
の頭文字をとったもので、Webアプリケーションアーキテクチャの1つです。
Model
: リソース、ロジックView
: 画面表示、表現Controller
: 入力の受け取りに合わせてModel
とView
を使う司令塔Railsは以下のアーキテクチャになっています。
Controller
の前にRouter
がいますが、MVC
の形をとっていることがわかると思います。処理を順を追って紹介していきますね。Routing
ユーザーからリクエストを受け取ると、RailsアプリケーションのRouterはそのHTTPメソッドとパスから定義に合わせてController(のAction)に処理を渡してくれます。リソースを処理
リクエストを受け取ったControllerはデータの操作が必要な場合はModelに指示を出します。例えば、『ID=1のユーザーのモデルオブジェクトをくれ!』みたいなやつです。ModelはそれにしたがってDBを更新したりオブジェクトを検索してControllerに返してあげます。画面をお返し
Controllerはその後、Viewに画面をレンダリングするように指示を出します。この時、先ほどゲットしたModelの情報などもViewに渡し、Viewはその情報も元にして画面を整形してControllerに返却します。
ControllerはユーザーにViewを渡してあげて、ユーザーのブラウザがそれを表示してくれます。これらがMVCの、そしてRailsの一連の処理の流れになります。こうやってみるととてもシンプルですよね。MVCがそれぞれ独立したことにより、コードの管理も簡単だし、どこに何をやらせればいいのかもシンプルに考えられるようになると思います。
RailsのMVCをScaffoldで確認する
RailsのScaffoldはRailsを体現したようなやつなんですよ。なんで当然MVCなわけですね。
てことでScaffoldのソースコードを少し覗きながらMVCを感じてみましょう!Router
Router
の設定はconfig/routes.rb
に書きます。覗いてみましょー!config/routes.rbRails.application.routes.draw do resources :users endえ、超シンプルやん。はい、
resouces [controller_name]
でそのControllerに対してRailsアプリケーションで標準的に必要とされるルーティングを全て生成してくれちゃう便利なメソッドです。実際に以下のルーティングを生成してくれちゃいます。
HTTP method Path Routing Route name GET /users users#index users POST /users users#create users GET /users/new users#new new_user GET /users/:id/edit users#edit edit_user GET /users/:id users#show user PATCH /users/:id users#update user PUT /users/:id users#update user DELETE /users/:id users#destroy user 見方ですが、例えば1行目であれば
『GET
メソッドで/users
にアクセスされた場合、UsersController
のindex action
にルーティングする。Rails内ではusers_path
って名前で定義される』
って感じです。「名前で定義される」ってなんぞ?となると思いますが、この後でてきます。例えばリンク(<a>
)を作る時にRailsではlink_to
ヘルパーが使えるのですがその遷移先としてuser_path
と指定すれば/users
と解釈してくれるんです。これ結構便利なんですよねー。RailsのRouting設定はコマンドラインから確認することができるっす。
# rails routes Prefix Verb URI Pattern Controller#Action users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy ...上の表とおんなじ感じになっていることがわかりますね。
Controller
さて、RouterによってControllerのActionにリクエストがルーティングされましたんで、Controllerの中身を覗いてみましょう!
Controllerのソースコードはapp/controller/
配下にまとまっています。今回はuser
モデルを作ったのでusers_controller.rb
ファイルが生成されていますね。Controllerはその中に複数のactionがあることからusers
のように複数形で名前づけされるルールになってますので気をつけてください!app/controller/users_controller.rbclass UsersController < ApplicationController before_action :set_user, only: [:show, :edit, :update, :destroy] def index @user = User.all end def show end def new @user = User.new end def edit end def create @user = User.new(user_params) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.json { render :show, status: :created, location: @user } else format.html { render :new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @user.update(user_params) format.html { redirect_to @user, notice: 'User was successfully updated.' } format.json { render :show, status: :ok, location: @user } else format.html { render :edit } format.json { render json: @user.errors, status: unprocessable_entity } end end end def destroy @user.destroy respond_to do |format| format.html { redirect_to users_url, notice: 'User was successfully destroyed.' } format.json { head :no_content } end end private def set_user @user = User.find(params[:id]) end def user_params params.require(:user).permit(:name, :email) end endながいっすね。重要なところだけかいつまんで説明します。
まず、def xxx ... end
となってるブロックがいっぱいありますね。def
はRubyにおける関数定義です。で、private
より上にある一つ一つがActionと呼ばれているやつらです。ちょうど先ほどRouterで定義されていたアクションが全てあるのがわかりますね。その中で1つ、index actionをみてみましょうか。
app/controllers/users_controller.rb... def index @user = User.all end ...中身一行だけですね。
これは@user
にUser.all
の結果を代入してますね。User.all
はまた今度詳しく説明予定ですが、Userモデルのデータを全てリスト形式で取得するメソッドです。なのでUserモデルを全件検索したものを@user
に代入しているんですね。
ここで気になる人がいると思うのですが、@
ってなんやねんと。これは、インスタンス変数と呼ばれるものになります。対して@
がつかない変数はローカル変数と呼びます。
違いは変数の適用範囲です。簡単にいうとローカル変数はViewに引き渡すことができないのです。対してインスタンス変数はViewに引き渡すことができるのです。MVCの考え方からControllerはViewにModelの情報を引き渡してユーザーに描写する画面を作るので、インスタンス変数を使う必要があるのです。さて、ControllerがModelからデータを受領しているのはここまででなんとかわかると思いますが、Viewの呼び出しはどうやっているのか...
RailsではViewを呼び出すメソッドとしてrender
があります。users_controller.rb
の中にもrender
と書かれているところがありますがないところもあります。これはどういうことか。
実はRailsでは各Actionの最後に暗にActionと同じ名前のViewにrender
をしています。例えばindex
アクションの場合は、処理の最後にrender :index
というようなことがなされており、これによってapp/views/users/index.html.erb
が呼び出されるようになっています。Model
Modelのソースは
app/models/
に作ります。Scaffoldのおかげでuser.rb
ファイルが生成されていますので中身を覗いてみましょう。app/models/user.rbclass User < ApplicationRecord endApplicationRecordを継承しているので、特に何も書かなくてもDBにアクセスしてCRUDできるようになっています。
追加でバリデーションやロジック(デフォルト値や値の計算など)を書くことができます。(今後やっていきます!)実際にDBに反映されているテーブルの情報はSchemaをみることで確認することができます。
db/schema.rbActiveRecord::Schema.define(version: 2020_01_16_115651) do enable_extention "plpgsql" create_table "users", force: :cascade do |t| t.string "name" t.string "email" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end endString型の
name
、created_at
、updated_at
がusers
テーブルに作られた感じがわかりますよね。View
Viewのソースは
app/views/{controller_name}/
ディレクトリに作成します。app/views/users/index.html.erb<p id="notice"><%= notice %></p> <h1>Users</h1> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.email %></td> <td><%= link_to 'Show', user %></td> <td><%= link_to 'Edit', edit_user_path(user) %></td> <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New User', new_user_path %>これは
index
アクションが処理をさせるViewです。ほぼHTMLですね。
ファイルは.html.erb
拡張子です。.erb
はembedded Rubyの意で、Rubyのコードを埋め込めるHTMLファイルです。
Rubyコードの埋め込みの仕方には2種類あります。
- <% code %>: このcodeは実行されますが、結果はレンダリングされません。
- <%= code %>: このcodeは実行され、結果はレンダリングされます。
また、ブロック形式で記述することもできます!
index.html.erb
の中でも以下のような表現がありますね。app/views/users/index.html.erb... <% @users.each do |user| %> ... <% end %> ...この表現は、
@users
(これはControllerでUser.all
が代入されていたやつです。)の配列の中から1つずつ取り出しuser
という変数として、end
までの処理をまわすという表現です。はい。ということでScaffoldで作成されたファイルの中身をみながら「へー。RailsはMVCでRESTだなー。」となっていただけましたかね。
と、いうことでせっかく作ったScaffoldですが、便利すぎてお勉強には不向きなところもあるのでリセットして、次回からは1からアプリ開発をしていきたいと思います。
ScaffoldをClean up
rails generate
で作成したファイルや追加されたコードのほとんどはrails destroy
でもとにもどせます。# rails destroy scaffold userこいつは便利だ。ちなみに
destroy
はd
と省略することも可能。しかし、
scaffolds.scss
だけは消えないのでこれは個別に消してあげて!# rm app/assets/stylesheets/scaffolds.scssまた、DBにはまだテーブルが存在してる状態です。今回は開発環境ですし、データが消えても問題ないのでDBを再作成してclean upしましょう。
# rails db:migrate:resetこのコマンドはDBを削除(
db:drop
)してまた作り(db:create
)、マイグレーションを適用する(db:migrate
)を一度に実行してくれるコマンドです。最初にDBを削除してしまうので本番環境やテストデータを残しておきたい時は絶対に使ってはいけませんよ。まとめ
今回はScaffoldというRailsのアーキテクチャが詰まったアプリを作る機能を紹介しました。
その中でMVCやRESTといったRailsの開発思想が学べましたね。この辺りはアプリのシンプルさを保つためにもぜひものにしておきましょう。次回からは、何回かに分けてTwitterのようなアプリを1からつくってこうと思います。最初は静的なトップページ。
Bootstrap(CSSフレームワーク)を使っていい感じにデザインしてきますよ!では、次回も乞うご期待!ここまでお読みいただきありがとうございました!
Reference
- Ruby on Rails チュートリアル:実例を使って Rails を学ぼう
- Fielding Dissertation: CHAPTER 5: Representational State Transfer (REST)
- Webサービス開発で知っておきたいRESTfulの意味とは? - WPJ
P.S. 間違っているところ、抜けているところ、説明の仕方を変えるとよりわかりやすくなるところなどありましたら、優しくアドバイスいただけると助かります。