20200207のRailsに関する記事は15件です。

Rails Params

コントローラーにたどり着くデータが格納されているハッシュオブジェクトのようなもの。
a.png

新規投稿ページにフォームを記載

ルーティングを設定。
その後newからcreateにつなげる
a.png

()に登録する情報を記載
a.png
a.png

ストロングパラメーター

指定したキーを持つパラメーターのみを受け取るようにするもの。
a.png

プライベートメソッド

クラス外から呼び出すことのできないメソッドのこと。private以下に記載して、プライベートメソッドとして扱う。
a.png
メリットは以下の2点ある。
1.Classの外部から呼び出されてしまうとエラーが起こってしまうのを防ぐ。
2.private以下の部分は目を通さなくて良くなる。
a.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

スクリーンショット 2020-02-07 21.09.21.png

以上のような階層です。

部分テンプレートを当てたい場所と、使用するテンプレートについて

テンプレート化したいものはsharedファイルの中にある

_header.html.erb っというファイル

部分テンプレートを使用する場所は

new.html.erb

ファイルをまたいでいるため、shared/テンプレ化したファイル名
っという記述であってるはず・・・・

っと思ったが、

スクリーンショット 2020-02-07 21.19.18.png

devise/shared/headerっというファイルを指定したら解決

<%= render "devise/shared/header" %>

上記の通り上の階層のdeviseを指定すると、部分テンプレートを使用できた。
謎でしたが・・・・とにかく解決した!10分くらいで解決したのが幸い。

ここは違う、ここはこうしたほうが良い等々ございましたらご指摘いただけますと幸いです。
最後までみていただきありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails ヘルパーメソッド

主にview(ビューファイル)でHTMLタグを出現させたりテキストを加工するために予めメソッド。セキュリティ対策、コードをシンプルにする効果がある。form_tag(投稿ページなどにおけるフォームの実装)、link_to(リンクの実装)、simple_format(投稿した文章を自動で見やすく整形する)などがある。

form_tagを利用する場合

a.png
a.png
ヘルパーメソッドはRubyとして取り扱われるので、<%= %>(erbタグ)で囲んで使用する。/postsはルーティングのURIパターン、method: :postはHTTPメソッドを表す。
a.png

ビューファイルに実装する。

例:新規投稿ページにアクセスするためのリンクを追加
a.png
リンクに表示する文字は新規投稿、リンク先のURLはhttp://localhost:3000/posts/newを使用。/posts/newと省略することもできる。

form_with メソッド

a.png
特徴は3つある。
自動でパスを選択してくれて、HTTPメソッドを指定する必要が無い。
コントローラーから渡された、ActiveRecordを継承するモデルのインスタンスが利用できること(上記では@postがそれに該当)
inputタグは用いない。

ストロングパラメータを用いた場合

a.png

リダイレクト処理

「本来受け取ったパスとは別のパスへ転送する」機能のこと
a.png

バリデーション

データを登録する際に、一定の制約をかけること。
例:post.rb
これでタイトルと本文のいずれかが空の場合は保存処理が行われない。
a.png

simple_format メソッド

投稿時に改行を含むデータを送信したときに、その改行を反映してくれる役割がある。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

人の感情を可視化するアプリを作りました【キドアイラク】

はじめに

皆さん初めまして!
本記事は私がrailsで作った初めてのアプリである「キドアイラク」の紹介記事になっています。
スクリーンショット 2020-02-07 16.08.35.png

https://kidoairaku2019.herokuapp.com

この「キドアイラク」がどのようなアプリかというと、タイトル通り「人の感情を可視化する」アプリです。
自分がここ数日どんな感情で過ごしていたのか、他の人はどんな時にどんな感情を抱くのかを一目で確認することができます。
街中を歩く一人一人の感情が透けて見えるイメージです。
本サービスを作った背景や機能は後ほど詳しく語りたいと思いますので、もし興味がある方は読んで頂けると幸いです。

そして、僅か一ヶ月ほどで作ったのでショボい作りにはなっていますが、是非一度使っていただけると嬉しいです。

作った理由

ある一枚の画像

このサービスを作るきっかけになったのはある一枚の画像です。
lain.jpg
この画像は1998年に放送された『Serial experiments lain』というアニメのワンシーンです。
ネット上で顔の見えないアバターが好き勝手に意見を言い合っています。
このシーンを見たとき、現在SNS上で起こる炎上をうまく表現されていると感じました。
全く顔も表情も分からないユーザー同士が140字程度で意思疎通を図るなんて土台無理な話です。
元々SNSの炎上に対する嫌悪感があったので、この画像を見ながら「どうすれば炎上しないSNSを作れるだろうか」と考えていました。
そこで思い浮かんだのが「文章に感情を付ける」というアイデアでした。

今のSNSには「感情」が足りない

現実とインターネットの最大の違い、それは「感情」が見えるかどうかだと思います。
例えば、現実世界で挨拶する時、私たちは相手の表情、声のトーン、雰囲気から、相手がどんな感情かを判断することができます。
一方、インターネットの中では、どんな気分でいたとしても「おはようございます」の一言で表現できてしまいます(絵文字や顔文字が付く場合もありますが)。
これでは相手の気持ち、感情を全く理解することができません。
また、現在のSNSは構造上、どうしても自己顕示欲に塗れた人たちが多くなってしまうので、結果的に相手の意見を理解しようともせず自分の考えを押し付けるユーザーが発生してしまいます。
それがSNSで炎上が起こる原因だと感じました。
もし、ネット世界で相手の感情を簡単に理解できるようになれば、ネット上のコミュニケーションはどう変化するだろうか。
いつしかそんなことに頭が支配され始めました。

「感情」を健康にしたい

これはサービスを作り終わった後に思い付いたことです。
みんなジムに行ったり、ジョギングしたり、自分の身体を痛めつけることで健康を維持(確認)していますが、一週間に一回自分の感情を確認することは怠っています。
しかし、感情を確認することは非常に重要です。
自分がどんな時に感情を変化させるのか、最近の自分の感情はどんな割合なのか。
それを徹底的に理解しなければ、真の意味で健康にはなれないのではないでしょうか。

人の感情が知りたい

このサービスを作った最後の理由。
それは、「人の感情が知りたい」という単純な願望です。
私はある時期から、街中を歩いている一人一人が何を考えているのか、どんな感情で生きているのかと疑問に思って生きてきました。
この記事を読まれている方の中にも、そんな人がいると思います。
しかし、実際に街中の人に話しかけることもできず。
また、現状のSNSでは的確な感情把握ができません。
それなら自分で作るしかない、ということで「キドアイラク」を作ることを決めました。

キドアイラクの三つの機能

ここからは「キドアイラク」の主な機能について説明します。

自分の文章に感情をつける

スクリーンショット 2020-02-07 16.11.37.png
本サービスでは文章を投稿する際に「喜怒哀楽」の四つの感情をつけていただきます。
投稿された文章には感情が表示されるので、その文章がどんな感情で書かれたのか、一目でわかります。
また、文章を投稿するたびに自分の感情と向き合うことで、感情を俯瞰的に見る習慣がつき、結果的に自分の感情をコントロールしやすくなると考えています。
他にも、喜怒哀楽それぞれの投稿を見ることができるので、あまりネガティヴな意見を見たくない場合は、「よろこび」や「たのしい」の部分だけ見ていただくことも可能です。

自分の感情がグラフ化される

スクリーンショット 2020-02-07 16.23.19.png
マイページでは、最近自分がどんな気持ちでいるかを把握できる「感情グラフ」を見ることができます。
グラフは「当日」と「過去一週間」の二種類存在しており、他ユーザーの感情を見ることも可能です。
「怒りの感情が多いから減らそう」「もっと嬉しい気持ちを増やしたい!」といったように、日頃の感情を知ることで、自分を変えるきっかけを作ることができるのです。
他にも特定のワードがどのような感情のもと書かれているかを検索できる機能もありますので、ぜひお好きなワードを調べてお楽しみください。

承認欲求から解放される

他のSNSでは「他人から評価されたい」と考える自己承認欲求の強いユーザーが数多くいます。
その原因は、いいね数や(ツイッターで言う)リツイート数が表示されるからでしょう。
SNSに資本主義の要素を作ったことで、多くの人がその数字に囚われるようになってしまいました。
しかし、本来良質なコミュニケーションを築く上で、そういった数字を表示する機能は必要ありません。
現にインスタグラムはいいねの数を非表示にしましたし、ツイッターもいいね機能を失くす話が度々出ています。
そういったこともあり、キドアイラクでは「いいね機能」「シェア機能」「フォロー機能」を導入しないことで、必然的に承認欲求から解放される仕組みに設計しました。
誰かに認められようとするのではなく、常に自分と向き合い、成長しようと前を向き続ける向上心を持ちたい方にオススメのサービスです。

まとめ

全く0の知識から作ったので、ひとまず完成させられたことにホッとしています。
しかし、それ以上に圧倒的な技術不足を痛感しました。
自分が思ったようにできないことも多く、直さなければいけないところは山ほど存在します。
デザインも他所から拝借したものも多くありますから、それも直す必要がありそうです。
何より、自分の頭にあるものを形にする難しさを嫌という程知りました。
ものづくりって大変ですね。

最後にもう一度URLを貼っておきます。
ぜひ一週間ほど使ってみてください。
自分の感情と向き合い、自己分析してくだされば、このアプリの効果を実感していただけると思います。
https://kidoairaku2019.herokuapp.com/

ここまで読んでくださった皆さん、本当にありがとうございました。
エラーがなんども出て大変な時もありましたが、今回の経験を糧に、さらに色んなものを作っていきたいと思います。
その時はまたよろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

簡単なアプリケーションを作ってみる

railsでは簡単にこんなことができる!

「Ruby on RailsとはRubyのフレームワークだ」と聞きますね!
rails を使うとWebアプリケーションがつくれますが、rails を勉強していて、 スクリーンショット 2020-02-07 18.34.31.png

本当に簡単に(魔法のように)、簡単な(簡易的な)アプリケーションを作る方法を知りました。
それが、scaffoldジェネレータを利用した方法です。紹介したいと思います〜。

scaffoldとは?

rails のアプリケーションでは、MVC(モデル、ビュー、コントローラー)を使って一つ一つ作成していき、ルーティングを設定しますが、そういうのをまとめて自動的に作ってくれるのがscaffoldジェネレータなのですね。

どんなときに使う?メリット・デメリットは?

(私の中では)scaffoldジェネレータを使用するときは、このような時があげられます。

  • アプリケーションをすばやく作りたい!
  • アプリケーションを手っ取り早く作りたい!
  • アプリケーションをかーんたんに作りたい!
  • アプリケーションを試しに作りたい!

メリットはこちらです。

  • 技術力なくてもやってみたら作れる
  • アプリケーションの雛形となる部分を簡単に作成できる
  • 開発が効率的に進む
  • なので、とても便利!
  • rails の大まかな概要がある程度わかる

もちろんデメリットもあります。

  • あやふやな知識のままでもサービスを作れてしまう
  • なので、rails の深い理解が困難である

こんなのを作ってみる

ユーザーを作成し、投稿ができます。
ユーザーや投稿を、編集・削除できます。

アプリケーションの骨組みを作成する

ターミナルでお好きなディレクトリに、下のコマンドを実行し、アプリケーションの骨組みを作成します。

$ rails new greeting_app
$ cd greeting_app

ユーザーモデルを作る

アプリケーションのユーザーで使うモデルを作成します。
文字列にはstringを、整数にはintegerという型を使います!
integer型のidは、重複のないキーを割り当てられます。

カラム名
id integer
name string
email string

Usersリソースをscaffoldジェネレータで生成します。
scaffoldの引数には、リソース名を単数形にしたもの(user)にします。
データモデルの属性も一緒に追加します。
(idカラムはrailsによって自動的に自動的に追加されます!)

$ rails generate scaffold User name:string email:string

マイグレーションという1つのファイルが生成されました!(↓)
エディタで見ると、ファイル名の先頭には生成された時間が追加されているのがわかります。
そして、さっきのコマンドではオプションを追加していないt.timestampsが作られています。
これは、created_atupdated_atという2つのカラムを作成してくれます。

db/migrate/[timestamp]_create_users.rb
class 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 server

http://localhost:3000/ をブラウザで開きます。
このような画面になっているとOKですね!
?「わーい! Railsを使用しています!」って書いてます。
わーい

http://localhost:3000/users を開いて、ユーザー一覧を見てみましょう!
/usersをつけると、insexアクション(ユーザー一覧)が呼び出されます。

スクリーンショット 2020-02-07 19.21.07.png

まだユーザーは1人もつくられていないので、「New User」リンクを押し、「Name」「Email」を入力、「Create User」ボタンを押して作ってみましょう!作れました!
スクリーンショット 2020-02-07 18.34.31.png

※ちなみに、ユーザーをCreateした直後に画面上にでる緑の文字「User was successfully created.」はflashという機能を使っています!
スクリーンショット 2020-02-07 18.34.56.png

画面にリンクが色々あるのでなんとなく分かると思いますが、この時点でユーザーの編集も削除もできますね!

ユーザーに関するページ

ページごとにURLも作られています。

URL    アクション ページ内容
/users index すべてのユーザーを一覧するページ
/users/1 show idが1のユーザーを表示するページ
/users/new new 新規ユーザーを作成するページ
/users/1/edit edit id=1のユーザーを編集するページ

URLとアクションの組み合わせを変更する

今のままでは、/にアクセスしたときに「わーい! Railsを使用しています!」のままになっていて、/usersまで入力しないとアプリケーションを開けません。
そこで、ルーティングを変更してみましょう!(3行目を追加します。)

config/routes.rb
Rails.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 で使われていた言葉でした!

わーいわーいわーいわーいわーい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECS × ECR × Circle CiでRailsアプリケーションをデプロイ

前書き

・ECSのクラスターは起動タイプにFargateEC2がありますが、今回は使い慣れているEC2を使います。
・本記事はAWSの環境構築は全てマネジメントコンソールで行ってます。
(Terraformで1発でやりたいような人は他の記事を見るか、一応GitHubにTerraformでコード化もしているのでそちらを参考に)
・docker-composeは以下のような構成です(Nginxのコンテナ、Railsのコンテナ、Mysqlのコンテナ)

本記事で目指したいデプロイ構成

スクリーンショット 2020-02-11 10.08.44.png

(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.yml
config/database.yml
default: &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.rb
Rails.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:create

http://localhost
にアクセスするとRailsのデフォルト画面が表示されるはずです。
localhost(:80)にアクセスするとnginxのwebサーバに(裏ではnginxがpumaにリクエストしている)
localhost:3000にアクセスするとpumaのアプリケーションサーバにリクエストを投げていることになります。

スクリーンショット 2020-02-05 8.11.50.png

scaffoldでjsonを返す簡易apiを作成します。

$  docker-compose run app rails g scaffold Post title:string
$  docker-compose run app rails db:migrate
seeds.rb
5.times.each do |i|
  Post.create(title: "test#{i + 1}")
end

$ docker-compose run app rails db:seed

下の画像のようにjsonが返ってきてればOKです!

スクリーンショット 2020-02-07 20.43.36.jpg

ECRへのpush

AWSのマネジメントコンソールを開きます
ECRと検索します。
RailsとNginxのイメージ用のリポジトリをそれぞれ作成します。

リポジトリを作成をクリック
スクリーンショット 2020-02-05 9.23.52.png

まずはrailsのイメージから作成します。
リポジトリ名にはrails-apiを(任意のリポジトリ名で問題ありません)
スクリーンショット 2020-02-05 9.24.05.png

ECRヘのpushコマンドを表示します。
スクリーンショット 2020-02-05 9.28.59.png

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を選択

以下のように編集して作成します。
スクリーンショット 2020-02-07 4.25.12.png

RDSを作成する際にVPCが複数のAZで構成されている必要があるので
パブリックとプライベートサブネットそれぞれを1cのAZにも追加します。

サブネットのタブをクリック => サブネットの作成

スクリーンショット 2020-02-07 4.29.54.png

プライベートなサブネットも同様に作成します。
スクリーンショット 2020-02-07 4.29.13.png

public-1aサブネットのIPv4のアドレス指定動作を変更します。

スクリーンショット 2020-02-07 4.34.47.png

スクリーンショット 2020-02-07 4.34.55.png
[パブリック IPv4 アドレスの自動割り当てを有効にする] チェックボックスをオンにし、[Save (保存)] を選択します。

先ほど後から追加したpublic-1cですがデフォルトでは、プライベートルートテーブルが選択されるので。
public-1aのものと同じルートテーブルになるように修正します。

スクリーンショット 2020-02-07 4.39.23.png

public-1cを選択した状態でアクション => ルートテーブルの編集をクリック

スクリーンショット 2020-02-07 4.38.16.png

public-1aのルートテーブルのIDと同じルートテーブルのIDを選択して保存します。
スクリーンショット 2020-02-07 4.42.34.png

RDSの作成

エンジンのオプションでMySQLを選択
テンプレート => 無料枠

スクリーンショット 2020-02-07 0.32.21.png

=>VPCで先ほど作成したVPCを選択

スクリーンショット 2020-02-07 5.33.33.png

データベースの作成をクリック!

ECSでタスクの作成

マネジメントコンソールからECSを検索

左タブのタスク定義を選択 => 新しいタスク定義の作成をクリック

起動タイプの互換性: EC2を選択して次へ

スクリーンショット 2020-02-07 5.42.16.png

タスク定義名に任意の名前を入力します。
ネットワークモードにbridgeを選択

スクリーンショット 2020-02-07 0.35.47.png

一番下の方までスクロールしていくとボリュームの追加という項目があります。
・ボリュームの追加を選択
スクリーンショット 2020-02-07 21.45.14.png

ここでスコープをsharedに指定するThere is already a server bound to: <socket>あとで怒られてしまいます。taskにするように注意してください

中間の方まで戻リます。
タスクサイズは両方512を設定します。
**コンテナの追加というボタンがあるのでクリック
ここで
nginx*rails*のコンテナをそれぞれ追加していきます。

まずはnginxのコンテナから。

コンテナ名はnginx
イメージにECRリポジトリに登録してあるnginxイメージのURIをコピペします。
ポートマッピングにはホストを0、コンテナポートを80に設定します。

スクリーンショット 2020-02-07 5.49.35.png

マウントポイントで先ほど作成したsocketsボリュームをマウントします。
また、Cloud Watch Logsにログを吐き出したいのでログ設定にチェックします

スクリーンショット 2020-02-07 5.51.42.png

他はとりあえず全て空欄でokです!

次にrailsのコンテナを作成します。

先ほどと同様にイメージにECRのrailsイメージのURIをコピペし、ボリュームマウントにsocketsを指定し(パスも同様に/app/tmp/sockets)、ログ設定にもチェックをいれましょう。

ポートマッピング: ホストを0、コンテナポートを3000

また、起動時のコマンドを追加します。作業ディレクトリは/appで。
スクリーンショット 2020-02-07 6.09.38.png

bundle,exec,puma,-C,config/puma.rb

環境変数を追加します。

environmet.png

DB_HOST: RDSのエンドポイント
DB_DATABASE: RDSのDB識別子
RAILS_MASTER_KEY: ローカルのconfig/master.keyの値を貼り付けます。

右下の作成ボタンをクリック!

ローダバランサーの作成

マネジメントコンソールからEC2を検索 => 左タブのロードバランサーを選択
=> ロードバランサーの作成

ALBを選択して作成をクリック
スクリーンショット 2020-02-07 6.20.30.png

名前を適当に入力してAZの設定を行います。
今回は上で作成したVPCを選択し、パブリックサブネットのみ(public-1a、public-1c)を追加します。
スクリーンショット 2020-02-07 6.23.45.png

・セキュリティグループの設定
新しくセキュリティグループを作成します。

スクリーンショット 2020-02-07 6.27.47.png

・ルーティングの設定
ターゲットグループの作成をします
スクリーンショット 2020-02-07 7.46.07.png

・手順 5: ターゲットの登録
ECSの設定で登録するのでここではターゲットは登録せずに「次の手順:確認」をクリック

作成!

ECSでクラスタの作成

スクリーンショット 2020-02-07 6.40.31.png

ステップ1:クラスターテンプレートの選択
EC2 Linux + ネットワーキングを選択

ステップ2:クラスターの設定
EC2 インスタンスタイプにはm3.mediumを指定
キーペア: EC2インスタンスに接続するキーペアを指定します。

ネットワーキングの項目で今回作成したVPCを選択します。
スクリーンショット 2020-02-07 6.40.31.png

セキュリティグループは新規作成します。
後ほど、ここで新規作成したセキュリティグループを用いて、ECSによって起動するEC2インスタンス、RDS、ALBなどを全て繋ぎ合わせます。

作成をクリック!

作成が完了したら以下のような画面になります。
スクリーンショット 2020-02-07 6.47.18.png

クラスターを作成した時点でコンテナインスタンス(今回は2台)が立ち上がります。

サービスの作成

クラスター一覧で先ほど作成したクラスターを選択します。
サービスという項目に作成ボタンがあるのでそちらをクリックします

スクリーンショット 2020-02-07 18.59.12.png

ステップ 1: サービスの設定

タスク定義に作成済みのタスクを指定
クラスターに作成済みのクラスターを指定
サービス名に任意の名前を入力

サービス対応はレプリカを、
タスクの数は2を設定します。

ECSで言うタスクコンテナを意味します。

レプリカはクラスター全体で必要なコンテナ数を指定してそれを維持します。
デーモンでは、各コンテナインスタンスにコンテナのコピーを1つ配置し維持します。

スクリーンショット 2020-02-07 6.55.50.png

他は変更せずに次のステップ

ステップ 2: ネットワーク構成
ロードバランシングでApplication Load Balancerにチェックをいれます。

スクリーンショット 2020-02-07 7.00.31.png
スクリーンショット 2020-02-07 7.01.20.png

サービスの検出の統合の有効化のチェックを外します。

ステップ 3: Auto Scaling (オプション)
・今回はサービスの必要数を直接調整しないをチェックして次のステップへ

サービスの作成をクリック!

このサービスの作成で、これまで作成してきたクラスタとタスク、ALBを全て繋ぎ合わせることができました。

セキュリティグループの設定

ここが重要です!
今まで作成してきたコンポーネント間のトラフィックを許可するためにECSのクラスター作成時に一緒に新規作成したセキュリティグループのインバウンドを以下のように修正します。

スクリーンショット 2020-02-11 11.23.16.png

また、EC2インスタンスからRDSにアクセスできるようにします。
[サービス]タブで、RDSを検索してクリック => 左側のメニューで、「データベース」をクリック。
次に、作成したデータベースを見つけてクリック => 下のタブでセキュリティグループをクリック

スクリーンショット 2020-02-07 5.36.13.png

以下のようにインバウンドを編集します。

スクリーンショット 2020-02-11 11.28.21.png

EC2インスタンスにSSHログイン

スクリーンショット 2020-02-07 7.14.45.png

IPv4 パブリック IPをコピーしておきます。

ターミナルを開きます。

$ ssh -i [キーペアのpath] ec2-user@[パブリック IP]

スクリーンショット 2020-02-07 7.16.35.png

$ docker ps

とするとコンテナが立ち上がっていることがわかります。
スクリーンショット 2020-02-07 7.18.19.png
ちなみに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

スクリーンショット 2020-02-07 7.24.35.png

[ALBのDNS名]/postsにアクセスして以下のようにjsonが返ってきていれば大成功です!!!

スクリーンショット 2020-02-07 7.27.24.png

※基本的にコンテナのログは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.15

AWS_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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【実体験をもとに】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月の段階から就活をスタートする方が効率的かもしれません。

私は仕事が忙しく、とても無理でしたが・・・。

終わり

以上が私がプログラミング学習を始めて〜内定に至るまでの過程です。
長文を読んでいただきありがとうございます。
最後に私のプログラマー転職を成功に導いてくれた要因を列挙します。

  • コツコツと勉強を続けていく持続力
  • 「プログラミング楽しい!」とまでは行かないまでも、特に苦にならないという相性。
  • 初対面の人とも仲良くなれるコミュニケーション能力。
  • 即行動・即実践する意識。
  • アドバイスをしてくれるエンジニア仲間。
  • ほどほどに休憩を取っていたこと。
  • 無職状態になったとしても生活できるだけの貯金があったこと。
  • くじけそうな時に支えてくれた家族。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでja.ymlが反映されない

railsにてja.ymlに追記をしたが反映されなかった

ja.yml
#変更前(反映されなかったもの)
ja:   
    activerecord:
      attributes:
     board:
          name: 名前
          title: タイトル
          body: 本文

#変更後
ja:   
    activerecord:
      attributes:
        board:
          name: 名前
          title: タイトル
          body: 本文

boardのインデントが問題で反映されなかったよう。
直したら反映された。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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」にしたけど、ルールとかあるのかしら)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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'))

さいごに

コーティング規約については毎日更新します。
皆様の復習等にご活用頂けますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RSpecのassignsメソッドを復習するぞ

assignsメソッドの使い方

assignsメソッドはコントローラのインスタンス変数をテストするメソッド。
引数にインスタンス変数をシンボル型で渡す。(超重要)

categories_controller_spec.rb
require '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というテストデータが一致しているかを検証している。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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/rspotify

gem '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.rb
class 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.rb
Rails.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/

検索デモもできるので便利です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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の仕組みわからない
いい理解方法ないものか

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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:

  1. 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.

  2. Ensure you have defined root_url to something in your config/routes.rb.
    For example:

    root to: "home#index"

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

    <%= notice %>


    <%= alert %>

  4. 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.

  5. 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

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コード書いたことない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のシェルです。シェルというとbashzshなどが思い浮かぶと思いますが、alpine linuxではashです。

これでコンテナの中に入れたかと思います。今までローカルでコマンドを実行するときは$を頭につけていましたが、コンテナ内でコマンドを実行するときは#をつけるようにします。#がついている場合は、上のコマンドを実行してコンテナ内に入っていると思ってください。

何も言わずに以下のコマンドを実行してみましょう。

# rails generate scaffold user name:string email:string
# rails db:migrate

これだけですでに以下のようなアプリができています。 http://localhost:3000/users にアクセスしてみて確かめてみてください。↓のようなアプリが出来上がっているはずです。
image.png
色々と触ってみてください。たった2コマンドでこのアプリができちゃうの強すぎませんか?笑

ではまずコマンドの説明をしておきます。

rails generate scaffold model_name [field:type...field:type]

rails generate scaffoldはScaffoldでRailsアプリを作成するコマンドです。generategと省略できます。ちなみに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)を原則としています。リソースを中心に考えるとそれに対する操作とはいわゆるCRUDCreate/Read/Update/Delete)であるといえます。REST APIではHTTPメソッドのPOST/GET/PATCH(PUT)/DELETEをそれに対応させて定義しています。
RailsでもROAを原則としてアプリを設計していくことが理想です。

3. リソースを一意に識別する「汎用的な構文」

汎用的な構文...なんだこれもうわかりにくくないだろうか。
これは、例えばユーザーモデルであれば/usersのパスで操作ができる、商品モデルなら/purchasesのパスで操作できる、って感じです。

4. アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」

もうなんともですね。笑
これはHTTPとか使いましょう。って話です。

まとめると以下のような図になると思ってます。
image.png
このように、「URL」で「リソース」を指定し「HTTPメソッド」で「操作(CRUD)」を指定するイメージですね。
大切な考え方として「リソース」が主軸にあるということを抑えましょう。

先ほどScaffoldで生成したアプリケーションをみてみてもUserモデルを作成して、参照して、更新して、削除する、アプリケーションでした。アプリケーションを考える上でも、このRESTfulを念頭におきながらアーキテクトするとRailsで超絶作りやすくなりますね。

MVC

MVCModelViewControllerの頭文字をとったもので、Webアプリケーションアーキテクチャの1つです。

  • Model: リソース、ロジック
  • View: 画面表示、表現
  • Controller: 入力の受け取りに合わせてModelViewを使う司令塔

Railsは以下のアーキテクチャになっています。
image.png
Controllerの前にRouterがいますが、MVCの形をとっていることがわかると思います。処理を順を追って紹介していきますね。

Routing

image.png
ユーザーからリクエストを受け取ると、RailsアプリケーションのRouterはそのHTTPメソッドとパスから定義に合わせてController(のAction)に処理を渡してくれます。

リソースを処理

image.png
リクエストを受け取ったControllerはデータの操作が必要な場合はModelに指示を出します。例えば、『ID=1のユーザーのモデルオブジェクトをくれ!』みたいなやつです。ModelはそれにしたがってDBを更新したりオブジェクトを検索してControllerに返してあげます。

画面をお返し

image.png
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.rb
Rails.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にアクセスされた場合、UsersControllerindex 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.rb
class 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
...

中身一行だけですね。
これは@userUser.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.rb
class User < ApplicationRecord
end

ApplicationRecordを継承しているので、特に何も書かなくてもDBにアクセスしてCRUDできるようになっています。
追加でバリデーションやロジック(デフォルト値や値の計算など)を書くことができます。(今後やっていきます!)

実際にDBに反映されているテーブルの情報はSchemaをみることで確認することができます。

db/schema.rb
ActiveRecord::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

end

String型のnameemail、Datetime型のcreated_atupdated_atusersテーブルに作られた感じがわかりますよね。

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

こいつは便利だ。ちなみにdestroydと省略することも可能。

しかし、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

P.S. 間違っているところ、抜けているところ、説明の仕方を変えるとよりわかりやすくなるところなどありましたら、優しくアドバイスいただけると助かります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む