- 投稿日:2020-10-23T23:32:30+09:00
Railsに動画を挿入する方法
- 投稿日:2020-10-23T23:29:16+09:00
お名前ドットコムで取得したドメインが急に使用出来なくなった時
デプロイで使用しているのは、RDS、EC2、route53です。
今回、ターミナルでコマンドdig 取得したドメイン
でstatusを確認したら
status: NXDOMAINが見つかり、これを解決するために一日かかりました。急に使えなくなった場合の解決策は、
①IPアドレスでアクセスできるか確認する。IPアドレスでアクセスできた場合、下記の内容確認。
①お名前ドットコムにログインし重要なお知らせが来ていないか確認する。
②メールに重要メールが届いていないか確認する。私の場合は、メールに
20xx年xx月xx日12:00までに登録情報の修正をお願いします。と届いていたのですが
それに気づかずに指定の日付を超えてしまった為、ドメインが使用できなくなっていました。
登録情報を修正したら、3日後ぐらいにドメインが使用できるようになりました。
お名前ドットコムからのメール多い....
- 投稿日:2020-10-23T23:15:49+09:00
Railsでドットが2つ並んだやつに出くわした
カリキュラムにあったっけ?
はじめに見た時は、普通に記述ミスかと思いました。
メンターさんに聞いた時も初めは見たことないですね。と仰っていました!
調べてこれはオブジェクトと言うことを教えていただきました。下記が問題のコードです。
date: @todays_date..@todays_date + 6)これは、2点ドットですが、3点ドットもあります。
範囲オブジェクトというそうです。
SQLに保存する時に使用するみたいで、
・コードが少なく可読性が高い
・エラーになりにくい
上記のようなメリットがあるそうです。どんな使いかた?
railsUser.where(age: ...30)上記のコードが
SQLSELECT "users".* FROM "users" WHERE "users"."age" < 30たしかに短くなる。
初めの方のコードは、範囲抽出(Beetween)といいます。
簡単に言うと左の値から、右の値までって感じですね!下記のページ参照させていただきました。
気になる人は見てみてください!【Rails】範囲オブジェクト(Range)を使ったActiveRecordのwhere比較、範囲検索のコードの書き方https://simple-minds-think-alike.hatenablog.com/entry/active-record-where-with-range
- 投稿日:2020-10-23T22:51:54+09:00
ローカルサーバー起動できない!時の対処法
Ruby on Railsでpictweetのアプリケーション作成中。
ローカルサーバーを再起動しようと思ったが "cotroll + c"を入力しても反応なし。
ターミナルを強制終了し、再度立ち上げてから "rails s"を入力。すると、エラー発生。
”Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)”
とのことで、なにやら3000番のポートが使用中だそうだ(よくわかってない)。「ターミナルを再起動した時にローカルサーバーが立ち上がらない」
という状況である。サーバーを終了しないままターミナルを閉じた時に生じる現象らしい。
色々調べた結果、
1、lsofコマンドでポートで実行中のファイルを確認する
2、そのファイルをkillコマンドで削除するという手順で解決した。
1、lsofコマンドでポートで実行中のファイルを確認する
$ lsof -i :3000今回は3000番ポートなので、最後の数字を3000で入力。
結果が↓COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 8376 SHIGEDEEN 13u IPv4 0xa2239c9f9d219327 0t0 TCP localhost:hbci (LISTEN) ruby 8376 SHIGEDEEN 14u IPv6 0xa2239c9f85859677 0t0 TCP localhost:hbci (LISTEN) ruby 8376 SHIGEDEEN 25u IPv6 0xa2239c9f92497157 0t0 TCP localhost:hbci->localhost:58898 (CLOSE_WAIT) ruby 8376 SHIGEDEEN 27u IPv6 0xa2239c9f7cc60a37 0t0 TCP localhost:hbci->localhost:58871 (CLOSE_WAIT) ruby 8376 SHIGEDEEN 28u IPv6 0xa2239c9f6f09fb37 0t0 TCP localhost:hbci->localhost:58879 (CLOSE_WAIT) ruby 8376 SHIGEDEEN 29u IPv6 0xa2239c9f9040b777 0t0 TCP localhost:hbci->localhost:58885 (CLOSE_WAIT)ここで、PID接続しているものを消せばよいらしい。
2、実行中ファイルをkillコマンドで削除する
というわけで 8376 を killコマンドで消します。
kill -QUIT 8376または、
kill -QUIT <PID>これで、サーバーを再起動することができるようになりました。
参考文献
今回参考にさせていただいた記事はこちら?
(ローカルサーバを停止せずにターミナルを閉じてしまいました。:http://song-of-life.hatenablog.com/entry/2017/02/02/204010)
(げ!ローカルサーバーを切らずにターミナルを消しちゃった!:https://qiita.com/nagao_norihiro/items/aba40bd4e0eac9f9a92d)ちなみに、lsofコマンドは他にも有用な使い道があるようだ。
(lsofコマンド入門:https://qiita.com/hypermkt/items/905139168b0bc5c28ef2)
- 投稿日:2020-10-23T22:27:15+09:00
DelegationError について(Active Storage)
ポートフォリオ作成中
DelegationError
とエラーが出てその下に内容が
variant delegated to attachment, but attachment is nil
(google翻訳)添付ファイルに委譲された変形体で、添付ファイルがnilである
とエラーが出ました。解決方法
私のアプリはInstagramのようなアプリを開発しているので写真がないためこのエラーが出たと仮説を立て
データベースをリセットすることでこの問題を解決することができました!!対策として
このエラーの対策として、写真を保存するカラムにイメージが存在しないと保存ができないようにしてこのエラーが出ないように使用と思います
- 投稿日:2020-10-23T20:49:06+09:00
Rails Tutorial 第2章学習編
Rails Tutorial 第2章で(。´・ω・)ん?って思ったところ
演習
CSSを知っている読者へ: 新しいユーザーを作成し、ブラウザのHTMLインスペクター機能を使って「User was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?Google Chrome Shift+Ctrl+I or (F12) or 右クリックした中にある検証をクリック
HTML・CSSコードが見れます、
この機能を使って「User was successfully created.」を調べろって事だと思います('ω')ノ
もう少し詳しく知りたい方は⇒こちらをどうぞ簡単な内容のおさらい。
ユーザー登録機能を作る
魔法のコマンド 『 Rails g scaffold 』( scaffoldは日本語で足場という意味 )$ rails generate scaffold User name:string email:string $ rails db:migrateこのたった2つコマンドを叩くだけでこんなページが出来上がる。
ユーザー登録が出来る・・・もはや魔法の領域。
Scaffoldの欠点
- データ検証がない。(空欄・でたらめなアドレスでも登録できちゃう)
- ユーザー認証がない。(ログイン・ログアウト機能はない。誰でもユーザーページにアクセスできちゃう)
- レイアウトやスタイルが整っていない。
- テストが書かれていない。
- 理解が困難。
投稿機能を作る
$ rails generate scaffold Micropost content:text user_id:integer $ rails db:migrate先ほどと同じく2つコマンドを叩くだけとはいかない。
※ルーティングを追加する必要がある。ruby config/routes.rbRails.application.routes.draw do resources :microposts # ←これを追加するとurl/micropostで投稿ページにアクセスできる resources :users root 'users#index' endmodels/micropost.rbにvalidatesを追加する事で検証機能を実装できる
ruby app/models/micropost.rbclass Micropost < ApplicationRecord validates :name, length: { maximum: 140 } #入力できる文字列は140文字まで presence: true #文字列が入力されている事を確認する end異なるデータモデル同士の関連付ける
ruby app/models/user.rbclass User < ApplicationRecord #ユーザーはマイクロポストを沢山持ってるのでhas many :micropostを追加 has_many :microposts endruby app/models/micropost.rbclass Micropost < ApplicationRecord #マイクロポストはユーザーに紐づいているのでbelongs_to :userを追加 belongs_to :user validates :content, length: { maximum: 140 } endこれでRDBの関連付けが完了する。わ~い簡単( *´艸`)
Rails Console (Railsアプリを対話的に操作できる便利ツール)
# Rails コンソール $ rails c >> #ここにRubyコード記述をすると実行してくれる >> first_user = User.first # Userテーブルからidが1のユーザーを変数first_userに格納 コマンドの処理内容 User.first ↓ (自動的にデータベースを操作するSQLコマンドに変換される。) User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] ↓ SQLの実行結果 => #<User id: 1, name: "Michael Hartl", email: "michael@example.org", created_at: "2020-10-23 00:39:14", updated_at: "2020-10-23 00:41:24"> ↓ SQLの実行結果をfirst_userに格納 >> first_user.microposts #先ほどのユーザーが投稿したmicropostを全部取り出す。 Micropost Load (3.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ? [["user_id", 1], ["LIMIT", 11]] => #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "First micropost!", user_id: 1, created_at: "2020-10-23 02:04:13", updated_at: "2020-10-23 02:04:13">, #<Micropost id: 2, content: "Second micropost", user_id: 1, created_at: "2020-10-23 02:04:30", updated_at: "2020-10-23 02:04:30">]> >> micropost = first_user.microposts.first #first_userの1番目の投稿を変数micropostに格納感想
この章はあまり躓かなかったです。('ω')ノ
git&herokuの便利さに惚れ惚れしてきました。
- 投稿日:2020-10-23T20:27:39+09:00
[Ruby] 二次元配列の取り出し
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
二次元配列とは
- 配列の中に配列が入っている形です。
- items_priceのハッシュの中にそれぞれのアイテムが配列として格納されています。
- さらに、1つ1つのアイテムの中にも名前と値段の配列が入っています。
items_price = [["pen", [100, 200, 120]], ["book", [120, 150, 220]], ["pen_case", [1000, 1500]]]二次元配列を取り出すには
- each文を使ってハッシュを取り出します。
- 今回は二次元なので2回each文を使っているのですね。
items_price = [["pen", [100, 200, 120]], ["book", [120, 150, 220]], ["pen_case", [1000, 1500]]] items_price.each do |item| sum = 0 item[1].each do |price| sum += price end puts "#{item[0]}の値段は#{sum}円です。" endでは、penを例に取って一つずつみていきます。
1回目のeach(2行目)
items_price.each do |item| ~ end # => items_price配列の中の["pen", [100, 200, 120]]を取り出し、ブロック変数itemに代入2回目のeach(4行目)
item[1].each do |price| ~ end # => item配列の中の[100, 200, 120]を取り出し、ブロック変数priceに代入
- ちなみに、item[1]はprice配列の要素の数、つまりここでは3回繰り返すことになります。
出力する
puts "#{item[0]}の値段は#{sum}円です。"
- item[0]はitem配列の添字が0、["pen", [100, 200, 120]]の"pen"の部分になります。
結果
penの値段は420円です。 bookの値段は490円です。 pen_caseの値段は2500円です。
- 投稿日:2020-10-23T19:11:51+09:00
【Rails6 Vue.js】axiosを使ってCSVインポート処理を実装する
Vue.jsとRailsAPIを使って複数のCSVファイルをそれぞれのテーブルにインポートする必要があったので記録しておきます。
ご留意ください
Rails,Vue.js学習中の初学者が備忘録を兼ねて書いています。
内容に誤りを含む可能性・さらに良い手法がある可能性が多分にありますので、参考にする際はその点ご留意ください。
何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。実現したいこと
inputボックスを用意し、選択したCSVファイル(2種類)をそれぞれ用意したテーブルにaxiosを使ってPOSTしたい。
csv1 ⇨ code_listsテーブル
csv2 ⇨ financialsテーブル
テーブルの定義は下記の通りです。code_listsテーブルcreate_table "code_lists", force: :cascade do |t| t.string "edinet" t.string "securities" t.string "company" t.string "sector" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["company"], name: "index_code_lists_on_company" t.index ["edinet"], name: "index_code_lists_on_edinet", unique: true t.index ["securities"], name: "index_code_lists_on_securities" endfinancialsテーブルcreate_table "financials", force: :cascade do |t| t.string "edinet" t.date "rec_date" t.string "account_name" t.float "value" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["account_name"], name: "index_financials_on_account_name" t.index ["edinet", "rec_date", "account_name"], name: "index_financials_on_edinet_and_rec_date_and_account_name", unique: true t.index ["edinet"], name: "index_financials_on_edinet" end下準備
事前にライブラリを追加します。
config/application.rbrequire 'csv' #追記Gemのrooを追加して
bundle install
しますGemfilegem 'roo'
axios-post
時にcsrf
トークン対策が必要な為、別途プラグインを設定します。
plugins
フォルダを新たに作成してください。app/javascript/packs/plugins/vue-axios.jsconst VueAxiosPlugin = {} export default VueAxiosPlugin.install = function(Vue, { axios }) { const csrf_token = document.querySelector('meta[name="csrf-token"]').getAttribute('content') axios.defaults.headers.common = { "X-Requested-With": "XMLHttpRequest", "X-CSRF-Token": csrf_token } Vue.axios = axios Object.defineProperties(Vue.prototype, { axios: { get () { return axios } } }) }エントリーファイルにプラグインをimportします
hello_vue.jsimport Vue from "vue/dist/vue.esm"; import axios from "axios"; // 追加 import VueAxiosPlugin from "./plugins/vue-axios"; // 追加 import App from "./components/App.vue"; Vue.use(VueAxiosPlugin, { axios: axios }) // 追加 new Vue({ el: "#app", render: h => h(App), })ルーティング
ルーティングは次のように設定しました。
必要な箇所のみ記載しています。
それぞれRailsAPIのルーティング設定にしています。
code_listsテーブル用のcsvファイルはapi/code_lists/importへ
financialsテーブル用のcsvファイルはapi/financials/importへPOSTします。config/routes.rbRails.application.routes.draw do (上記省略) namespace :api, format: 'json' do resources :code_lists do post :import, on: :collection end end namespace :api, format: 'json' do resources :financials do post :import, on: :collection end end (以下省略) endView
ビューは次のようにしました。
Import.vue<template> <div> <div class="import-form"> <input @change="selectedFile" type="file" name="file"> </div> <div class="import-form"> <button @click="upload('/api/code_lists/import')" type="submit">コードリストのアップロード</button> </div> <div class="import-form"> <button @click="upload('/api/financials/import')" type="submit">財務データのアップロード</button> </div> </div> </template> <script> import axios from 'axios' export default { data: function(){ return { uploadFile: null }; }, methods: { selectedFile: function(e) { // 選択された File の情報を保存しておく e.preventDefault(); let files = e.target.files; this.uploadFile = files[0]; }, upload: function(url) { // FormData を利用して File を POST する let formData = new FormData(); formData.append('file', this.uploadFile); // let config = { // headers: { // 'content-type': 'multipart/form-data' // } // }; axios .post(url, formData) .then(function(response) { // response 処理 }) .catch(function(error) { // error 処理 }) } } } </script>inputボックスのファイル選択後にselectedFileメソッドでファイルをuploadFileに保存します。そして、buttonのクリックイベントでuploadメソッドが実行されます。uploadメソッドの引数のurl(先ほどroutesで設定した2つのurl)へファイルをPOSTします。POSTする際に事前に保存したuploadFileをFormDataオブジェクトに渡している事がポイントです。
今回はconfigは使用しなかった為コメントアウトしました。サーバサイド
今回は2つのcsvファイルをそれぞれのテーブルにImportする実装となり、それぞれのモデル毎に実装が必要となりますが、ほぼ同じ内容となる為Financial Modelの実装のみ記載しておきます。
まずコントローラについて。app/controllers/api/financials_controller.rbclass Api::FinancialsController < ApplicationController def import Financial.import(params[:file]) end endコントローラはFinancial Classのクラスメソッドを呼び出すだけとなります。
続いて、financialモデルの記述は以下の通りです。
app/models/financial.rbclass Financial < ApplicationRecord validates :edinet, presence: true validates :rec_date, presence: true validates :account_name, presence: true validates :value, presence: true def self.import(file) CSV.foreach(file.path, headers: true) do |row| # IDが見つかれば、レコードを呼び出し、見つかれなければ、新しく作成 financial = find_by(edinet: row["edinet"], rec_date: row["rec_date"], account_name: row["account_name"]) || new # CSVからデータを取得し、設定する financial.attributes = row.to_hash.slice(*updatable_attributes) # 保存する financial.save end end def self.updatable_attributes ["edinet", "rec_date", "account_name", "value"] end endインポートしたいCSVのカラム名をupdatable_attributesに入力。
またfind_byで既に取り込み済みのレコードかどうかを確認しており、取り込み済みの場合は上書きされます。最後に
現何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。
上場企業の財務データを活用したアプリケーションを開発中です。フロントエンドをVue.js、バックエンドはRailsAPIを使って開発を進めています。引き続き、得られた知見は記事にしてまとめていきたいと思います。
ここまでお付き合いいただきありがとうございました!参考にさせていただいた記事:
csrf対策:【Vue】axiosで、デフォルトでCSRFトークンを設定できるようにする
フロントエンド実装:Vue.js でファイルをポストしたいとき
バックエンド実装:【Ruby on Rails】CSVインポート
- 投稿日:2020-10-23T19:11:51+09:00
【Rails6+Vue.js】axiosを使ってCSVインポート処理を実装する
Vue.jsとRailsAPIを使って複数のCSVファイルをそれぞれのテーブルにインポートする必要があったので記録しておきます。
ご留意ください
Rails,Vue.js学習中の初学者が備忘録を兼ねて書いています。
内容に誤りを含む可能性・さらに良い手法がある可能性が多分にありますので、参考にする際はその点ご留意ください。
何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。実現したいこと
inputボックスを用意し、選択したCSVファイル(2種類)をそれぞれ用意したテーブルにaxiosを使ってPOSTしたい。
csv1 ⇨ code_listsテーブル
csv2 ⇨ financialsテーブル
テーブルの定義は下記の通りです。code_listsテーブルcreate_table "code_lists", force: :cascade do |t| t.string "edinet" t.string "securities" t.string "company" t.string "sector" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["company"], name: "index_code_lists_on_company" t.index ["edinet"], name: "index_code_lists_on_edinet", unique: true t.index ["securities"], name: "index_code_lists_on_securities" endfinancialsテーブルcreate_table "financials", force: :cascade do |t| t.string "edinet" t.date "rec_date" t.string "account_name" t.float "value" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["account_name"], name: "index_financials_on_account_name" t.index ["edinet", "rec_date", "account_name"], name: "index_financials_on_edinet_and_rec_date_and_account_name", unique: true t.index ["edinet"], name: "index_financials_on_edinet" end下準備
事前にライブラリを追加します。
config/application.rbrequire 'csv' #追記Gemのrooを追加して
bundle install
しますGemfilegem 'roo'
axios-post
時にcsrf
トークン対策が必要な為、別途プラグインを設定します。
plugins
フォルダを新たに作成してください。app/javascript/packs/plugins/vue-axios.jsconst VueAxiosPlugin = {} export default VueAxiosPlugin.install = function(Vue, { axios }) { const csrf_token = document.querySelector('meta[name="csrf-token"]').getAttribute('content') axios.defaults.headers.common = { "X-Requested-With": "XMLHttpRequest", "X-CSRF-Token": csrf_token } Vue.axios = axios Object.defineProperties(Vue.prototype, { axios: { get () { return axios } } }) }エントリーファイルにプラグインをimportします
hello_vue.jsimport Vue from "vue/dist/vue.esm"; import axios from "axios"; // 追加 import VueAxiosPlugin from "./plugins/vue-axios"; // 追加 import App from "./components/App.vue"; Vue.use(VueAxiosPlugin, { axios: axios }) // 追加 new Vue({ el: "#app", render: h => h(App), })ルーティング
ルーティングは次のように設定しました。
必要な箇所のみ記載しています。
それぞれRailsAPIのルーティング設定にしています。
code_listsテーブル用のcsvファイルはapi/code_lists/importへ
financialsテーブル用のcsvファイルはapi/financials/importへPOSTします。config/routes.rbRails.application.routes.draw do (上記省略) namespace :api, format: 'json' do resources :code_lists do post :import, on: :collection end end namespace :api, format: 'json' do resources :financials do post :import, on: :collection end end (以下省略) endView
ビューは次のようにしました。
Import.vue<template> <div> <div class="import-form"> <input @change="selectedFile" type="file" name="file"> </div> <div class="import-form"> <button @click="upload('/api/code_lists/import')" type="submit">コードリストのアップロード</button> </div> <div class="import-form"> <button @click="upload('/api/financials/import')" type="submit">財務データのアップロード</button> </div> </div> </template> <script> import axios from 'axios' export default { data: function(){ return { uploadFile: null }; }, methods: { selectedFile: function(e) { // 選択された File の情報を保存しておく e.preventDefault(); let files = e.target.files; this.uploadFile = files[0]; }, upload: function(url) { // FormData を利用して File を POST する let formData = new FormData(); formData.append('file', this.uploadFile); // let config = { // headers: { // 'content-type': 'multipart/form-data' // } // }; axios .post(url, formData) .then(function(response) { // response 処理 }) .catch(function(error) { // error 処理 }) } } } </script>inputボックスのファイル選択後にselectedFileメソッドでファイルをuploadFileに保存します。そして、buttonのクリックイベントでuploadメソッドが実行されます。uploadメソッドの引数のurl(先ほどroutesで設定した2つのurl)へファイルをPOSTします。POSTする際に事前に保存したuploadFileをFormDataオブジェクトに渡している事がポイントです。
今回はconfigは使用しなかった為コメントアウトしました。コントローラーとモデル
今回は2つのcsvファイルをそれぞれのテーブルにImportする実装となり、それぞれのモデル毎に実装が必要となりますが、ほぼ同じ内容となる為Financial Modelの実装のみ記載しておきます。
まずコントローラについて。app/controllers/api/financials_controller.rbclass Api::FinancialsController < ApplicationController def import Financial.import(params[:file]) end endコントローラはFinancial Classのクラスメソッドを呼び出すだけとなります。
続いて、financialモデルの記述は以下の通りです。
app/models/financial.rbclass Financial < ApplicationRecord validates :edinet, presence: true validates :rec_date, presence: true validates :account_name, presence: true validates :value, presence: true def self.import(file) CSV.foreach(file.path, headers: true) do |row| # IDが見つかれば、レコードを呼び出し、見つかれなければ、新しく作成 financial = find_by(edinet: row["edinet"], rec_date: row["rec_date"], account_name: row["account_name"]) || new # CSVからデータを取得し、設定する financial.attributes = row.to_hash.slice(*updatable_attributes) # 保存する financial.save end end def self.updatable_attributes ["edinet", "rec_date", "account_name", "value"] end endインポートしたいCSVのカラム名をupdatable_attributesに入力。
またfind_byで既に取り込み済みのレコードかどうかを確認しており、取り込み済みの場合は上書きされます。最後に
現何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。
上場企業の財務データを活用したアプリケーションを開発中です。フロントエンドをVue.js、バックエンドはRailsAPIを使って開発を進めています。引き続き、得られた知見は記事にしてまとめていきたいと思います。
ここまでお付き合いいただきありがとうございました!参考にさせていただいた記事:
csrf対策:【Vue】axiosで、デフォルトでCSRFトークンを設定できるようにする
フロントエンド実装:Vue.js でファイルをポストしたいとき
バックエンド実装:【Ruby on Rails】CSVインポート
- 投稿日:2020-10-23T18:15:20+09:00
RailsのAPIモードをCookie(session)認証に対応させる
Vue.js + RailsのAPIモードの認証方式をauth_tokenからsession(cookie)に変更した時の変更点をまとめる
これを始めた理由
既存のauth_token認証がWebアプリにとってセキュアでない。
- auth_tokenをlocal storageに入れるためxssによる乗っ取りのリスクがある。
- https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851
代理ログインの要件がある
- 普通のwebアプリで実装する予定の管理画面でログインしたユーザーとSPAで作られた管理画面にシームレスにログインさせるには
- OAuthサーバーを作るか
- Cookie(Session)の従来の認証に変える必要がある。
今回は納期優先でsession認証に変更
Cookie認証に必要だったもの
config/application.rb
# Only loads a smaller set of middleware suitable for API only apps. # Middleware like session, flash, cookies can be added back manually. # Skip views, helpers and assets when generating a new resource. config.api_only = false # <- true を false に変更session storeをcookieにする場合は
config.api_only = true
にした上で必要なmiddle wearを読み込む方法で行けたが、それはそれで
- Deviseと相性が悪い
- session storeにredisを使いたい
という理由でredis storeを使う時は、この方法以外に手段がなかった。
application_controller.rb (全ての基底のcontroller)
class ApplicationController < ActionController::API include ActionController::Cookies #<- これを追加ActionController::API を継承して作る場合はこの設定も必要
axios(ajaxライブラリ)
axios.create({ // credential = cookie withCredentials: true, //... })ajax側にCORS対応としてCookieを送る機能を利用する。
- 投稿日:2020-10-23T17:11:34+09:00
#Rails Tutorial 第1章学習編
Rails Tutorial 第一章で(。´・ω・)ん?って思ったところ
Cloud9のユーザー登録
Cloud9は現在Amazon Web Services (AWS) に統合されたため、Cloud9を使うためにはAWSアカウントが必要になります。AWSアカウントを既にお持ちの場合は、AWSにログインしてください。AWSコンソールに行き、検索ボックスから “Cloud9” と入力すると、Cloud9の開発環境を作成するためのページに行けます。
Amazon Web Services (AWS) アカウントを持っていない場合は、AWS Cloud9のユーザー登録をします。悪用防止のためクレジットカード情報の入力が必須になりましたが、Railsチュートリアルのワークスペースは1年間無料なのでご安心ください。アカウントが有効になるまで最大で24時間かかりますが、著者の場合は約10分ほどで完了しました。
Cloud9の管理ページ (図 1.4) に無事たどり着いたら “Create environment” をクリックし、図 1.5のような画面になるまで進めてください。情報を適宜入力して、確認ボタンを押して進めていくと、最終的にCloud9の開発環境を手に入れることができます (図 1.6)。このとき “root” ユーザーであるという警告メッセージが表示されるときがありますが、こちらの対処方法は後ほど説明します (IAMという機能を使った対応方法について13.4.4で説明します)。
引用:https://railstutorial.jp/chapters/beginning?version=5.1#sec-development_environmentこれじゃわかんねーよって感じだったのでYoutube上にあったcloud9の登録方法説明動画を参考にしました。
コマンドでどうやってファイル開けばいいの? を解決
#Rails tutorialには便利なc9をインストール('ω')ノ #c9 <ファイル名> でファイルを開けるよ。 npm install -g c9このコマンド何してるの? その1
Rubyのインストールで無駄な時間を使わないようにするために追記 $ echo "gem: --no-document" >> ~/.gemrc UNIXコマンドの処理内容 echo "gem: --no-document" ("gem: --no-documentを) >> (末尾に追記してね。) ~/.gemrcファイル (ホームディレクトリの下にある~/.gemrcというファイルに)このコマンド何してるの? その2
JavaScriptソフトウェアの依存関係を管理するYarnをインストール $ source <(curl -sL https://cdn.learnenough.com/yarn_install) UNIXコマンドの処理内容 source ファイルに書かれたコマンドを現在のシェルで実行するコマンド <() : プロセス置換(コマンドの出力結果をファイルとして扱う機能) curl -sL https://cdn.learnenough.com/yarn_install curl [http://対象のURL] HTTPリクエストを実施し結果を標準出力へ -s -- 余計な出力をしない -L -- リダイレクトがあったらリダイレクト先の情報を取る yarn_installファイルの中身です。 #!/bin/bash # Installs YARN on AWS Cloud9 Ubuntu Server. curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get -y update && sudo apt-get -y install yarn やっと全貌が見えました! 以下のコマンドを実行してるんですね・・・! curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get -y update && sudo apt-get -y install yarncurl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get -y update && sudo apt-get -y install yarnこれって・・・なんでしょう?
自分のプラットフォームに合ったYarnインストール手順(英語)
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get -y update && sudo apt-get -y install yarnJavaScriptソフトウェアの依存関係を管理するYarnをインストールする為のコマンドって事だった。
このコマンド何してるの? その3
sudo ln -sf `which nano` /usr/bin UNIXコマンドの処理内容 sudo 管理者で実行 ln -sf シンボリックリンク(ショートカット)を作成 /usr/binという場所に飛ぶwhich nanoという名前のショートカットを作成?クラウドIDEを使う場合は、次にGitで使うデフォルトのエディタを設定します(編集や、“amend”でプロジェクトを変更するのに使われます)。ここでは、比較的使いやすくクラウドIDEのデフォルトエディタでもあるnanoエディタを使うことにしましょう。この設定を書き込んでもログアウト時にデフォルトエディタはログアウトしてしまいますし、パスも正しくないので、を実行してシンボリックリンク(symlinkとも呼ばれます)を作成してnanoの実行ファイルを正しく指すようにしましょう (初心者には少々難しいので、今読んで理解できなくても心配は不要です)。
(。´・ω・)ん? でどうすりゃいいの? まぁ飛ばすか( ^ω^)・・・。
Rails Tutorialで使用するデータベースソフト(SQL)について
cloud9(開発環境)ではsqliteを使用。
HerokuではPostgreSQLを使用。
開発環境と本番環境は同じSQLを使う事が推奨。なんで違うの使っているだろう学習の為なのかな?(´-ω-`)分からない。
Amazon RDS での AWS 無料利用枠
DB インスタンスを各月で連続して実行するのに十分な、MySQL、MariaDB、PostgreSQL、Oracle BYOL、または SQL Server (SQL Server Express Edition) などを使う Amazon RDS の Single-AZ db.t2.micro インスタンスのための、750 時間という使用時間
Oracle BYOL db.t3.micro Single-AZ インスタンスの使用は、Amazon RDS の無料利用枠に含まれています。Oracle BYOL の上で、db.t2.micro Single-AZ と db.t3.micro Single-AZ のインスタンスを両方実行する場合、その使用量はインスタンスクラス全体で合計されます。
20 GB の汎用 (SSD) DB ストレージ*
自動データベースバックアップとユーザーによる任意の DB スナップショットに使用できる 20 GB のバックアップストレージ*PostgreSQL使えるのに・・・なんでだろう。。。
Railsインストール関連
Railsをインストール RubyGemsが提供するgemコマンドを使う。 gem install rails -v 6.0.3 gem install [アプリ] -v [バージョン指定]
#Railsで空のテンプレート作成コマンド rails _6.0.3_ new hello_app rails _[version]_ new [アプリ名]Gemfile.はインストールするライブラリ(部品)を記述するファイルsource 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.6.3' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.0.3' # Use sqlite3 as the database for Active Record gem 'sqlite3', '~> 1.4' # Use Puma as the app server gem 'puma', '~> 3.11' # Use SCSS for stylesheets gem 'sass-rails', '~> 5' # Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker gem 'webpacker', '~> 4.0' # Turbolinks makes navigating your web application faster. # Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.7' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use Active Model has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use Active Storage variant # gem 'image_processing', '~> 1.2' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.4.2', require: false group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a # debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] end group :development do # Access an interactive console on exception pages or by calling 'console' # anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the # background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end group :test do # Adds support for Capybara system testing and selenium driver gem 'capybara', '>= 2.15' gem 'selenium-webdriver' # Easy installation and use of web drivers to run system tests with browsers gem 'webdrivers' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]#Gemfileの中に記載されてるライブラリを一括インストールするコマンド bundle install #インストールしたライブラリに依存関係で問題が発生した場合に使うコマンド bundle update#Railsサーバーの立ち上げコマンド rails server rails s #(省略形) ← こっちの方がよく使うrb config/environments/development.rbRails.application.configure do . . . # Cloud9 への接続を許可する config.hosts.clear ←これ追記しないとRailsサーバーへのアクセスで弾かれる endGit関連
Gitはソースコードを管理する便利なアプリ
Githubはインターネット上にソースコードを保管する場所を提供してくれるサービス# Gitで使う名前の設定とメールアドレス設定 # ※Gitに設定する名前やメールアドレスは、今後リポジトリ上で一般に公開されるので注意 $ git config --global user.name "名前" $ git config --global user.email メールアドレス # checkoutコマンドをcoに省略できるようにする。 $ git config --global alias.co checkout # git pushする時にパスワード要求される時間を変える 毎回パスワード打つのめんどさを軽減 $ git config --global credential.helper "cache --timeout=86400" # リポジトリ(保存箱)を作るコマンド $ git init # 一時保存箱にファイルを入れるコマンド -A は変更(新規・追加・削除)があったファイルを全て追加という意味 $ git add -A # 一時保存箱にメモを付けて保存箱へ移すコマンド -m "メッセージ" でメモを書ける $ git commit -m "Initialize repository" # インターネット上にある自分のソースコード置き場をoriginという名前で登録 $ git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git # 自分のアップロード $ git push -u origin master # 変更があるかを確認できる $ git status # 過去にcommitした内容を確認 $ git logHeroku関連
Herokuはインターネット上でアプリを公開させてくれるサービス(5個まで無料)
ソースコードのバージョン管理にGitを使っていれば、Railsアプリケーションを簡単に公開できる開発環境と本番環境で環境が違うのでそれに合わせてインストールするライブラリを変更する必要がある。
cloud9(開発・テスト環境) = sqlite3 Heroku(本番環境) = PostgreSQLruby.Gemfilesource 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem 'rails', '6.0.3' gem 'puma', '4.3.4' gem 'sass-rails', '5.1.0' gem 'webpacker', '4.0.7' gem 'turbolinks', '5.2.0' gem 'jbuilder', '2.9.1' gem 'bootsnap', '1.4.5', require: false #ここから上は全て共通でインストールするんだと思う('ω')ノ #開発環境とテスト環境のみインストール group :development, :test do gem 'sqlite3', '1.4.1' gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw] end #開発環境のみインストール group :development do gem 'web-console', '4.0.1' gem 'listen', '3.1.5' gem 'spring', '2.1.0' gem 'spring-watcher-listen', '2.0.1' end #テスト環境のみインストール group :test do gem 'capybara', '3.28.0' gem 'selenium-webdriver', '3.142.4' gem 'webdrivers', '4.1.2' end #本番環境のみインストール group :production do gem 'pg', '1.1.4' end # Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]#本番用以外のgemをインストールする $ bundle install --without productionpg gemを追加したことやRubyバージョンを指定したことをGemfile.lockに反映させないと、
本番環境へのデプロイで失敗してしまうためです。#herokuコマンドのインストール source <(curl -sL https://cdn.learnenough.com/heroku_install) 実行してる中身のコマンドはこれ! curl -OL https://cli-assets.heroku.com/heroku-linux-x64.tar.gz tar zxf heroku-linux-x64.tar.gz && rm -f heroku-linux-x64.tar.gz sudo mv heroku /usr/local echo 'PATH=/usr/local/heroku/bin:$PATH' >> $HOME/.profile source $HOME/.profile > /dev/null# herokuにログインする (--interactiveオプションを使うとブラウザをかずにログインできる) $ heroku login --interactive # Herokuに新しいアプリケーションを作成する (gitのソースコードを解析して適切なサーバーを用意) $ heroku create # ソースコードをアップロードする これでネット上に自分の作ったサービスが公開される。 $ git push heroku master感想
Cloud9・Git・Herokuを使ってHello Worldだけど公開サービスができた!
アプリ開発だけで終わる本が多い中でサービスを公開まで1章で紹介されているのは本当にすごいと思う。
アウトプットする事でUNIXコマンドで躓いた部分を調べて謎が解けた。
UNIXコマンド・・・(゜-゜) 事前学習読んだんだけどな
source 、(プロセス置換) <()、curl、 In こんなん書いてあったっけ・・・。さぁ 2章も張り切って頑張るぞー( `ー´)ノ
- 投稿日:2020-10-23T17:11:34+09:00
Rails Tutorial 第1章学習編
Rails Tutorial 第一章で(。´・ω・)ん?って思ったところ
Cloud9のユーザー登録
Cloud9は現在Amazon Web Services (AWS) に統合されたため、Cloud9を使うためにはAWSアカウントが必要になります。AWSアカウントを既にお持ちの場合は、AWSにログインしてください。AWSコンソールに行き、検索ボックスから “Cloud9” と入力すると、Cloud9の開発環境を作成するためのページに行けます。
Amazon Web Services (AWS) アカウントを持っていない場合は、AWS Cloud9のユーザー登録をします。悪用防止のためクレジットカード情報の入力が必須になりましたが、Railsチュートリアルのワークスペースは1年間無料なのでご安心ください。アカウントが有効になるまで最大で24時間かかりますが、著者の場合は約10分ほどで完了しました。
Cloud9の管理ページ (図 1.4) に無事たどり着いたら “Create environment” をクリックし、図 1.5のような画面になるまで進めてください。情報を適宜入力して、確認ボタンを押して進めていくと、最終的にCloud9の開発環境を手に入れることができます (図 1.6)。このとき “root” ユーザーであるという警告メッセージが表示されるときがありますが、こちらの対処方法は後ほど説明します (IAMという機能を使った対応方法について13.4.4で説明します)。
引用:https://railstutorial.jp/chapters/beginning?version=5.1#sec-development_environmentこれじゃわかんねーよって感じだったのでYoutube上にあったcloud9の登録方法説明動画を参考にしました。
AWS Cloud9の登録にはクレジットカードが必須
あんまりいないと思うけどクレカ作れない人向け(´-ω-`)
住信SBIネット銀行で口座開設すれば貰えるデビットカードで代用できます('ω')ノコマンドでどうやってファイル開けばいいの? を解決
#Rails tutorialには便利なc9をインストール('ω')ノ #c9 <ファイル名> でファイルを開けるよ。 npm install -g c9このコマンド何してるの? その1
Rubyのインストールで無駄な時間を使わないようにするために追記 $ echo "gem: --no-document" >> ~/.gemrc UNIXコマンドの処理内容 echo "gem: --no-document" ("gem: --no-documentを) >> (末尾に追記してね。) ~/.gemrcファイル (ホームディレクトリの下にある~/.gemrcというファイルに)このコマンド何してるの? その2
JavaScriptソフトウェアの依存関係を管理するYarnをインストール $ source <(curl -sL https://cdn.learnenough.com/yarn_install) UNIXコマンドの処理内容 source ファイルに書かれたコマンドを現在のシェルで実行するコマンド <() : プロセス置換(コマンドの出力結果をファイルとして扱う機能) curl -sL https://cdn.learnenough.com/yarn_install curl [http://対象のURL] HTTPリクエストを実施し結果を標準出力へ -s -- 余計な出力をしない -L -- リダイレクトがあったらリダイレクト先の情報を取る yarn_installファイルの中身です。 #!/bin/bash # Installs YARN on AWS Cloud9 Ubuntu Server. curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get -y update && sudo apt-get -y install yarn やっと全貌が見えました! 以下のコマンドを実行してるんですね・・・! curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get -y update && sudo apt-get -y install yarncurl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get -y update && sudo apt-get -y install yarnこれって・・・なんでしょう?
自分のプラットフォームに合ったYarnインストール手順(英語)
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get -y update && sudo apt-get -y install yarnJavaScriptソフトウェアの依存関係を管理するYarnをインストールする為のコマンドって事だった。
このコマンド何してるの? その3
sudo ln -sf `which nano` /usr/bin UNIXコマンドの処理内容 sudo 管理者で実行 ln -sf シンボリックリンク(ショートカット)を作成 /usr/binという場所に飛ぶwhich nanoという名前のショートカットを作成?クラウドIDEを使う場合は、次にGitで使うデフォルトのエディタを設定します(編集や、“amend”でプロジェクトを変更するのに使われます)。ここでは、比較的使いやすくクラウドIDEのデフォルトエディタでもあるnanoエディタを使うことにしましょう。この設定を書き込んでもログアウト時にデフォルトエディタはログアウトしてしまいますし、パスも正しくないので、を実行してシンボリックリンク(symlinkとも呼ばれます)を作成してnanoの実行ファイルを正しく指すようにしましょう (初心者には少々難しいので、今読んで理解できなくても心配は不要です)。
(。´・ω・)ん? でどうすりゃいいの? まぁ飛ばすか( ^ω^)・・・。
Rails Tutorialで使用するデータベースソフト(SQL)について
cloud9(開発環境)ではsqliteを使用。
HerokuではPostgreSQLを使用。
開発環境と本番環境は同じSQLを使う事が推奨。なんで違うの使っているだろう学習の為なのかな?(´-ω-`)分からない。
Amazon RDS での AWS 無料利用枠
DB インスタンスを各月で連続して実行するのに十分な、MySQL、MariaDB、PostgreSQL、Oracle BYOL、または SQL Server (SQL Server Express Edition) などを使う Amazon RDS の Single-AZ db.t2.micro インスタンスのための、750 時間という使用時間
Oracle BYOL db.t3.micro Single-AZ インスタンスの使用は、Amazon RDS の無料利用枠に含まれています。Oracle BYOL の上で、db.t2.micro Single-AZ と db.t3.micro Single-AZ のインスタンスを両方実行する場合、その使用量はインスタンスクラス全体で合計されます。
20 GB の汎用 (SSD) DB ストレージ*
自動データベースバックアップとユーザーによる任意の DB スナップショットに使用できる 20 GB のバックアップストレージ*PostgreSQL使えるのに・・・なんでだろう。。。
Railsインストール関連
Railsをインストール RubyGemsが提供するgemコマンドを使う。 gem install rails -v 6.0.3 gem install [アプリ] -v [バージョン指定]
#Railsで空のテンプレート作成コマンド rails _6.0.3_ new hello_app rails _[version]_ new [アプリ名]Gemfile.はインストールするライブラリ(部品)を記述するファイルsource 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.6.3' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.0.3' # Use sqlite3 as the database for Active Record gem 'sqlite3', '~> 1.4' # Use Puma as the app server gem 'puma', '~> 3.11' # Use SCSS for stylesheets gem 'sass-rails', '~> 5' # Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker gem 'webpacker', '~> 4.0' # Turbolinks makes navigating your web application faster. # Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.7' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use Active Model has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use Active Storage variant # gem 'image_processing', '~> 1.2' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.4.2', require: false group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a # debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] end group :development do # Access an interactive console on exception pages or by calling 'console' # anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the # background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end group :test do # Adds support for Capybara system testing and selenium driver gem 'capybara', '>= 2.15' gem 'selenium-webdriver' # Easy installation and use of web drivers to run system tests with browsers gem 'webdrivers' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]#Gemfileの中に記載されてるライブラリを一括インストールするコマンド bundle install #インストールしたライブラリに依存関係で問題が発生した場合に使うコマンド bundle update#Railsサーバーの立ち上げコマンド rails server rails s #(省略形) ← こっちの方がよく使うrb config/environments/development.rbRails.application.configure do . . . # Cloud9 への接続を許可する config.hosts.clear ←これ追記しないとRailsサーバーへのアクセスで弾かれる endGit関連
Gitはソースコードを管理する便利なアプリ
Githubはインターネット上にソースコードを保管する場所を提供してくれるサービス# Gitで使う名前の設定とメールアドレス設定 # ※Gitに設定する名前やメールアドレスは、今後リポジトリ上で一般に公開されるので注意 $ git config --global user.name "名前" $ git config --global user.email メールアドレス # checkoutコマンドをcoに省略できるようにする。 $ git config --global alias.co checkout # git pushする時にパスワード要求される時間を変える 毎回パスワード打つのめんどさを軽減 $ git config --global credential.helper "cache --timeout=86400" # リポジトリ(保存箱)を作るコマンド $ git init # 一時保存箱にファイルを入れるコマンド -A は変更(新規・追加・削除)があったファイルを全て追加という意味 $ git add -A # 一時保存箱にメモを付けて保存箱へ移すコマンド -m "メッセージ" でメモを書ける $ git commit -m "Initialize repository" # インターネット上にある自分のソースコード置き場をoriginという名前で登録 $ git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git # 自分のアップロード $ git push -u origin master # 変更があるかを確認できる $ git status # 過去にcommitした内容を確認 $ git logHeroku関連
Herokuはインターネット上でアプリを公開させてくれるサービス(5個まで無料)
ソースコードのバージョン管理にGitを使っていれば、Railsアプリケーションを簡単に公開できる開発環境と本番環境で環境が違うのでそれに合わせてインストールするライブラリを変更する必要がある。
cloud9(開発・テスト環境) = sqlite3 Heroku(本番環境) = PostgreSQLruby.Gemfilesource 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem 'rails', '6.0.3' gem 'puma', '4.3.4' gem 'sass-rails', '5.1.0' gem 'webpacker', '4.0.7' gem 'turbolinks', '5.2.0' gem 'jbuilder', '2.9.1' gem 'bootsnap', '1.4.5', require: false #ここから上は全て共通でインストールするんだと思う('ω')ノ #開発環境とテスト環境のみインストール group :development, :test do gem 'sqlite3', '1.4.1' gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw] end #開発環境のみインストール group :development do gem 'web-console', '4.0.1' gem 'listen', '3.1.5' gem 'spring', '2.1.0' gem 'spring-watcher-listen', '2.0.1' end #テスト環境のみインストール group :test do gem 'capybara', '3.28.0' gem 'selenium-webdriver', '3.142.4' gem 'webdrivers', '4.1.2' end #本番環境のみインストール group :production do gem 'pg', '1.1.4' end # Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]#本番用以外のgemをインストールする $ bundle install --without productionpg gemを追加したことやRubyバージョンを指定したことをGemfile.lockに反映させないと、
本番環境へのデプロイで失敗してしまうためです。#herokuコマンドのインストール source <(curl -sL https://cdn.learnenough.com/heroku_install) 実行してる中身のコマンドはこれ! curl -OL https://cli-assets.heroku.com/heroku-linux-x64.tar.gz tar zxf heroku-linux-x64.tar.gz && rm -f heroku-linux-x64.tar.gz sudo mv heroku /usr/local echo 'PATH=/usr/local/heroku/bin:$PATH' >> $HOME/.profile source $HOME/.profile > /dev/null# herokuにログインする (--interactiveオプションを使うとブラウザをかずにログインできる) $ heroku login --interactive # Herokuに新しいアプリケーションを作成する (gitのソースコードを解析して適切なサーバーを用意) $ heroku create # ソースコードをアップロードする これでネット上に自分の作ったサービスが公開される。 $ git push heroku master感想
Cloud9・Git・Herokuを使ってHello Worldだけど公開サービスができた!
アプリ開発だけで終わる本が多い中でサービスを公開まで1章で出来るって本当にすごいと思う。
今回のアウトプットでUNIXコマンドで躓いていただなぁっと調べて少し謎が解けた。
UNIXコマンド・・・(゜-゜) 事前学習読んだんだけどな
source 、(プロセス置換) <()、curl、 In こんなん書いてあったっけ・・・。まぁいいや、さぁ 2章も張り切って頑張るぞー( `ー´)ノ
- 投稿日:2020-10-23T16:17:43+09:00
項目内容の情報を保存する 〜Active_Hash〜
情報の登録フォーマットを実装する際に避けて通れないのが、選択した項目(collectionなど)をDBに保存すること。
フリマなどのアプリでは都道府県、商品の状態、配送日数などの登録が必要です。アンケートを想定するなら性別、生年月日など様々な場面でみられますね。
項目内容を予めseed.rbなどで用意してテーブルを作るということを想定する方も多くいると思いますが、これは無駄なテーブルを作っていると言っても過言ではありません。無駄なテーブル?
DB設計などでもよく扱われる内容が「正規化」です。ざっくり言ってしまうとデータの構造を効率的でシンプルにすることです。しかしこの正規化を徹底的に行ってしまうと、小さなテーブルが増えてしまいこれも処理の負荷の要因につながります。そのため項目専用テーブルを作ることは極力避けなければなりません。
そんな際に役立つのがActive_hashです
Active_hashとは?
専用モデルを作り、その中に予め項目内容の値を用意することでDBを介さずとも項目を用意することができます。言うなれば「モデル内に項目テーブル」を作ることになります。こうすることで小さなテーブルをDB側に用意する必要がなくなるため負荷が軽くなるのです。
導入手順
今回はcollection_selectを使った商品アンケートを想定して実装していこうと思います。
保存・管理したい内容は以下の4つです。
・年代
・性別
・商品を知った経緯
・商品を使ってみての感想DB負荷などを考えてテーブルは1つにしたいです。
設計としては
1.年代は10代〜90代
2.性別は男性・女性
3.商品を知った経緯は広告、知人、家族、インターネット
4.商品を使ってみての感想は手入力
としていきます。この中で項目(collection_select)として使用したいのは1~3番の内容です。
ではこれを想定してアンケートを実装していきましょう。
今回の解説はactive_hashの実装のみに留めますのでそれ以外の行程は割愛しますのでご了承ください。Step:1 Gemfileにactive_hashを追加しインストールを実行
gem 'active_hash'ターミナル
% bundle install
Step:2 モデル&マイグレーションファイルの用意
gコマンドでモデルを生成 ※モデル名はお好みで
% rails g model model question
・マイグレーションファイルの準備
active_hashを使う場合項目内容はintegerカラムで管理します。このintegerカラムがidとして動いてくれるのです。そのためカラム名は必ず"_id"をつけることを忘れないようにしましょう。
手入力欄についてはいつものtextカラムで実装します。00000000000000_create_questions.rb
class CreateQuestions < ActiveRecord::Migration[6.0] def change create_table :questions do |t| t.integer :age_id, null: false t.integer :sexuality_id, null: false t.integer :find_item_id, null: false t.text :comment, null: false t.timestamps end end endその後いつものようにテーブルを作成して、マイグレーションファイルを実行します。
% rails db:create % rails db:migrate
・項目ごとのモデルファイルを作成する
active_hashを実装するモデルを項目の3つ分を用意します。
マイグレーションファイルは必要ないのでオプションをつけてスキップさせます。% rails g model age --skip-migration % rails g model sexuality --skip-migration % rails g model find_item --skip-migration
では各項目用に準備したモデルの中身を書いていきましょう
生成したモデルの内部はおそらく初期はこのような形になっていると思います
class Age < ApplicationRecord endこれをactive_hash専用モデルにするため、以下のように編集を加えます。
class Age < ActiveHash::Base endこれにより、このモデル内で擬似的な項目テーブルを作れるようになりました。
項目をこの中に入れる際はクラスメソッドとハッシュを使って実装していきます。
可読性をあげるポイントは1つめのキーをidに、「もう1つのキーには項目として扱いたい名前をつけること。
例class クラス名 < ActiveHash::Base self.data = [ { id: 0, hoge: fuga }] endこれに沿って以下のようになります。
class Age < ActiveHash::Base self.data = [ { id: 0, name: '---' }, { id: 1, name: '10代' }, { id: 2, name: '20代' }, { id: 3, name: '30代' }, { id: 4, name: '40代' }, { id: 5, name: '50代' }, { id: 6, name: '60代' }, { id: 7, name: '70代' }, { id: 8, name: '80代' }, { id: 9, name: '90代' } ]class FindItem < ActiveHash::Base self.data = [ { id: 0, example: '---' }, { id: 1, example: '広告で知った' }, { id: 2, example: '知人の紹介で知った' }, { id: 3, example: '家族の紹介で知った' }, { id: 4, example: 'インターネットで知った' } ] endclass Sexuality < ActiveHash::Base self.data = [ { id: 0, name: '---' }, { id: 1, name: '男性' }, { id: 2, name: '女性' } ] endこれでactive_hashを使って擬似テーブルの作成は完了。
あとは大元となる一番最初に作ったquestionモデルに連携させる記述を施します。class Question < ApplicationRecord extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :age belongs_to_active_hash :sexuality belongs_to_active_hash :find_item endStep:3 ビューファイルの記述
<h1>当社の商品についてアンケートにご協力ください</h1> <div class="wrapper"> <div class="form"> <%= form_with model: @question, local: true do |f| %> <div class="form-box"> <h3>年代をお選びください</h3> <%= f.collection_select(:age_id, Age.all, :id, :name) %> </div> <div class="form-box"> <h3>性別をお選びください</h3> <%= f.collection_select(:sexuality_id, Sexuality.all, :id, :name)%> </div> <div class="form-box"> <h3>当社の商品をどこでお知りになりましたか?</h3> <%= f.collection_select(:find_item_id, FindItem.all, :id, :example)%> </div> <div class="form-text"> <h3>当社の商品をお使頂いてみての感想を簡単にで構わないのでご記入ください</h3> <%= f.text_area :comment %> </div> <%= f.submit "送信する" %> <% end %> </div> </div>ポイントはcollection_selectの引数です。
第一引数はparamsに渡す値(カラム名)、 第二引数には表示させたい項目(モデル名)。Step:4 コントローラの記述
class QuestionsController < ApplicationController def index @question = Question.new end def create # binding.pry @question = Question.new(question_params) @question.save redirect_to root_path end private def question_params params.require(:question).permit( :age_id, :sexuality_id, :find_item_id, :comment) end endここについては特に言及箇所はありません。
手短に実装を行ってみました
皆さんもぜひactive_hashに挑戦してみてください
- 投稿日:2020-10-23T11:52:42+09:00
画像をクリックすると詳細画面に遷移する方法
環境
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
目的
レポート一覧画面において、投稿されたレポートの画像をクリックすると詳細が見れるようにする。
結論: ネストを使用
画像をクリックした際に、詳細画面に遷移させるには、link_toメソッドにネストを用いることで解決できます。
do〜end
で囲む。index.html.erb<%= link_to report_path(report.id) do %> <div class="content_post"> <%= image_tag report.image if report.image.attached? %> <p>顧客名:<%= report.name %></p> <span class="name"> <%= report.date %> </span> </div> <% end %>まとめ
ネストは、ルーティングの設定の際にもどのレポートにコメントを行うのかの指定を出来、非常に役に立つ機能であると思います!
同じような悩みや壁にぶつかっている人の役に立てれば幸いです!
- 投稿日:2020-10-23T10:37:12+09:00
【0からCircleCIに挑戦】自動テストを構築する(Rails6.0・mysql8.0・Rspec)
背景
未経験から自社開発系企業の就職を目指します。良質なポートフォリオ作成のためCircleCIを勉強することにしました。
現状の知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。自分の忘備録かつ、同じくらいのレベルでこれからCircleCIに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。
最終目標
CircleCIでgit pushするたび自動テストが走るようにする。また自動テストをsuccessにする
【関連記事】
【0からCircleCIに挑戦】CircleCIの基礎を学ぶ環境
ruby 2.6.6
rails 6.0
db: mysql 8.0
test: rspec自動テストを構築する(Rails6.0・mysql8.0・Rspec)
githubとCircleCIの連携は完了している前提で進めます。
基本的には、circleCIの公式、または【circleCI】Railsアプリでgithubと連携してrubocopとrspecテストを走らせるなどを参考にしていけば自動テストは簡単に設定できると思います。ただ自動デプロイや今後より複雑な設定をしていくためには、ファイルの記述を分解し、理解する必要があります。まず全体を見ていきましょう。
ファイル全体
.circleci/config.yml```version: 2.1 jobs: #----------------------------------------------★ジョブ build: docker: #----------------------------------------------★Executor - image: circleci/ruby:2.6.6-node-browsers environment: RAILS_ENV: 'test' MYSQL_HOST: 127.0.0.1 MYSQL_USERNAME: 'root' MYSQL_PASSWORD: '' MYSQL_PORT: 3306 - image: circleci/mysql:8.0 command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'true' MYSQL_ROOT_HOST: '%' working_directory: ~/repo steps: #---------------------------------------------★ステップ - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "Gemfile.lock" }} - v1-dependencies- - run: name: install dependencies command: | bundle install --jobs=4 --retry=3 --path vendor/bundle - save_cache: paths: - ./vendor/bundle key: v1-dependencies-{{ checksum "Gemfile.lock" }} - run: mv config/database.yml.ci config/database.yml - run: bundle exec rake db:create - run: bundle exec rake db:schema:load - run: name: RSpec command: | mkdir /tmp/test-results TEST_FILES="$(circleci tests glob "spec/models/users_spec.rb" | \ circleci tests split --split-by=timings)" bundle exec rspec \ --format progress \ --out /tmp/test-results/rspec.xml \ --format progress \ $TEST_FILES - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results destination: test-results細かい記述は置いておき、前回の記事で触れた「ステップ」「ジョブ」「Executor(エグゼキュータ)」について整理しましょう。
- ステップは18行目に「steps」と書いてある箇所です。今回はステップを宣言している箇所が1箇所しかないので、ステップは1つです。「steps」以下はすべて1つのステップに属するコマンドリストです。
- ジョブは上から2行目に「jobs」と書かれている箇所で宣言されています。こちらも1つしか記述がないので、今回はジョブ1つです。「jobs」以下すべてがジョブの内容になります。ちなみにジョブ名は「build」です
- 「Executor(エグゼキュータ)」は4行目に書かれています。今回は「docker」と書かれているのでDocker Executorになります。「Docker」以下にある「image」の2箇所でイメージを取得し、コンテナを作成しています。
つまりまとめると、「このファイルは「build」というジョブが1つあり、そのジョブはdocker環境で実行され、実行内容はステップ(1つ)以下だよ」という意味になります。大まかな構造をみたので、次は1つ1つ細かく見ていきましょう。
① version~Executorの箇所
.circleci/config.ymlversion: 2.1 jobs: build: docker: - image: circleci/ruby:2.6.6-node-browsers environment: RAILS_ENV: 'test' MYSQL_HOST: 127.0.0.1 MYSQL_USERNAME: 'root' MYSQL_PASSWORD: '' MYSQL_PORT: 3306 - image: circleci/mysql:8.0 command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'true' MYSQL_ROOT_HOST: '%' working_directory: ~/repo
- versionはCircleCIのバージョンです。今から設定するのであれば2か2.1で良いかと思います。
- jobsはこれからジョブの内容を書くという宣言です。次の行のbuildがジョブの名前になります。ちなみにジョブが一つしかない場合は、ジョブ名はbuildでないといけないので気をつけましょう。
- dockerは「Executor(エグゼキュータ)」でdocker環境を構築してジョブを実行することを宣言しています。
- 1つめのimageはrubyのイメージを取得しています。rubyの前の「circleci/」はコンビニエンスイメージといいCircleCIが用意しているイメージのことを差します。
- enviroment以下はrubyイメージに対しての設定です。「RAILS_ENV: 'test'」はテスト環境であることを示し、「MYSQL_HOST: 127.0.0.1」は同じローカル内のMYSQLに接続することを差します。「MYSQL_USERNAME」・「MYSQL_PASSWORD」の箇所はMYSQLの設定です。こちらはテスト用のconfigファイルにも記述する必要があります。そのファイルに関しては後ほど説明します。「MYSQL_PORT: 3306」はMYSQLのポート番号です。
- 次にもう一つイメージがあり、こちらはMYSQLのイメージを作成しています。構成は同じでenvironment以下でイメージの環境設定をしています。ちなみに「command~」はmysqlの認証プラグインを変更しています。mysql8.o以降を使う際は必須ですのでお気をつけください。「MYSQL_ALLOW_EMPTY_PASSWORD: 'true'」はpasswordなしでもMYSQLにログインすることを許可しています。「MYSQL_ROOT_HOST: '%'」はどのホストからでもアクセス可能を示します。
- 「working_directory:」 はステップをどこで実行するかを示します。デフォルトだと「~/project」です。
では後半部分もみていきましょう。
② steps~の箇所
.circleci/config.ymlsteps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "Gemfile.lock" }} - v1-dependencies- - run: name: install dependencies command: | bundle install --jobs=4 --retry=3 --path vendor/bundle - save_cache: paths: - ./vendor/bundle key: v1-dependencies-{{ checksum "Gemfile.lock" }} - run: mv config/database.yml.ci config/database.yml - run: bundle exec rake db:create - run: bundle exec rake db:schema:load - run: name: RSpec command: | mkdir /tmp/test-results TEST_FILES="$(circleci tests glob "spec/models/users_spec.rb" | \ circleci tests split --split-by=timings)" bundle exec rspec \ --format progress \ --out /tmp/test-results/rspec.xml \ --format progress \ $TEST_FILES - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results destination: test-results
- 「steps」でステップのコマンドリストを記述することを宣言しています。
- 「-checkout」はリポジトリからコードを取り出しています。今回でいうとgithubの該当プロジェクトから取り出しています。ちなみにリポジトリからコードやデータを取り出すことをチェックアウトといいます。
- 「restore_cache」はキャッシュの読み込みです。キャッシュは前回の記事で説明しましたが、簡単にいうとジョブを素早く実行するための仕組みです。「key:〜」の2行分は,「Gemfile.lock」に変更があった場合にキャッシュの内容を更新するという意味です。
- 次の1つめの「-run」はbundle installを実行しています。nameは任意の名前です。またbundle installの後ろに「-job=4・・・」と書いてありますが、これは並列処理に関する記述で読み込みを高速化してくれます。
- 「save_cache」はキャッシュの保存です。ここで保存された内容(※bundle installのこと)が、次回以降「restore_chache」で読み込まれます。
- 「- run: mv config/database.yml.ci config/database.yml」でデータベースに関する設定を入れ替えています。「config/database.yml.ci」に関しては後述しますが、CircleCI用にわかりやすく別ファイルで用意したデータベース設定です。
- 次の2つの行でCircleCI用のデータベースを作成・反映しています
- そして「- run:name: RSpec」の箇所でようやくテストに関する記述をします。
- 「command: | 」で複数行にシェルコマンドがあることを宣言しています。以降の行ではテストの実行、実行結果の保存をしているという記述になります。ここは少し記述が複雑ですがCircleCI公式にも書いてあるので参照してください。テストを実行し、それを指定した場所に保存していると把握しましょう。
- 「store~」もテスト結果に関する表示ですが、こちらはテスト結果をCircleCIのアカウント上に表示させる記述です。
③database.yml.ci(ホスト上のファイル)
たびたび出てきましたが、CircleCI上のデータベースの設定ファイルも確認しましょう。
configtest: &default adapter: mysql2 encoding: utf8 pool: 5 username: <%= ENV.fetch("MYSQL_USERNAME") %> password: <%= ENV.fetch("MYSQL_PASSWORD") %> host: <%= ENV.fetch("MYSQL_HOST") %> port: <%= ENV.fetch("MYSQL_PORT") %> database: ci_testこちらはいつものdatabase.ymlファイルと変わらないので、ほとんど説明不要だと思います。ちなみに環境変数を利用しています。
以上で設定ファイルの説明は終わりです。あとは毎回git pushするたびにテストが実行されます。
下記がテスト実行画面です。すべてsuccessになっていることを確認しましょう。(※上から2番めのデータベースに関しては、falseが出てない限り問題ありません。データベースコンテナが正常どおり起動し、終了したマークになります)githubのプルリク上にも下記のように、自動テスト完了マークが表示されるかと思います。
まとめ・感想
CircleCIの公式が有能だったため、基本的には公式みればほとんどの疑問が解決できました。自動テストに関しては簡単に導入できそうです。ただ見た感じ自動デプロイに関しては少し難しそうなので、AWSやDockerの知識を復習しながら挑戦してみたいと思います。
参考
【書籍】
『CircleCI実践入門──CI/CDがもたらす開発速度と品質の両立 浦井 誠人 (著), 大竹 智也 (著), 金 洋国 (著) 』【qiita】
『いまさらだけどCircleCIに入門したので分かりやすくまとめてみた』
『【CircleCI】Railsアプリに導入(設定ファイルについて)』
- 投稿日:2020-10-23T08:33:59+09:00
lengthメソッドについて
lengthメソッド
文字列が持つメソッドです。
length(レングス)メソッドは文字列の文字数を数えてくれるメソッドです。
文字間の空白も数えられます。メソッドの使用は、
以下のように値に対してメソッド名「length」をドット.で繋ぎ実行します。【例】irb# 文字列の文字数を出す irb(main):001:0> "Hello World".length => 11"Hello World".lengthは、1つの式として見ることもできますね。
上の例で=>の後に表示されているのは、「Hello World」の文字数「11」です。
文字自体は、「10」文字ですが、「 」空白も入れての「11」文字になります。irbで以下のコードを実行してみましょう
では、実際にlengthメソッドを試してみましょう。
irb# lengthメソッドで文字数を出す irb(main):001:0> "good morning".length # 続けてこのように表示されれば成功 => 12まとめ
メソッドとは、プログラミングにおける何らかの処理をまとめたもの。
lengthメソッドとは、文字列の文字数を数えるメソッドのこと。
⚠︎空白(スペース)も数えられます。以上。
- 投稿日:2020-10-23T07:40:33+09:00
アンケートの「良かった」「ふつう」「悪かった」の割合(パーセンテージ)をSQLで算出する
やりたいこと
アンケートテーブル(surveys)に含まれる、「良かった」「ふつう」「悪かった」の割合(パーセンテージ)を出したい。
どんなSQLを書けば良いか?データの例
surveysテーブルの中身(全13件)
id user_id answer 1 251 良かった 2 113 良かった 3 46 ふつう 4 414 良かった 5 456 良かった 6 18 ふつう 7 173 ふつう 8 441 良かった 9 419 悪かった 10 157 ふつう 11 116 良かった 12 204 良かった 13 445 悪かった 算出したい値
- 良かった = (7件なので)53.8%
- ふつう = (4件なので)30.8%
- 悪かった = (2件なので)15.4%
対象RDBMS
- PostgreSQL 9.6
解答例
こんなSQLで算出できる。
SELECT TO_CHAR( 100.0 * SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END) / COUNT(*), '999.9%' ) AS "良かった", TO_CHAR( 100.0 * SUM(CASE WHEN answer = 'ふつう' THEN 1 ELSE 0 END) / COUNT(*), '999.9%' ) AS "ふつう", TO_CHAR( 100.0 * SUM(CASE WHEN answer = '悪かった' THEN 1 ELSE 0 END) / COUNT(*), '999.9%' ) AS "悪かった" FROM surveys出力結果
良かった ふつう 悪かった 1 53.8% 30.8% 15.4% 簡単な解説
SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END)
で「良かった」が何件あったのかをカウントする。(ここでは7)COUNT(*)
でテーブルの全件数をカウントする(ここでは13)- 上の2つの数値で割り算して100を掛ければ、パーセンテージが算出できる
- ただし、整数同士の割り算は整数値に丸められてしまうので、7÷13×100=0となってしまう。それを避けるため、100ではなく100.0を最初に掛ける。これにより小数点以下の値も算出される。(100.0×7÷13=53.8461538)
- 最後に
TO_CHAR
関数で数値をフォーマットする(TO_CHAR(53.8461538, '999.9%')
→53.8%
)- 同じ手順で「ふつう」と「悪かった」のパーセンテージを算出する
実際に実行してみる
以下のサイトにアクセスして"Run it"ボタンをクリックすると、SQLの実行結果を確認できる。
https://rextester.com/XINWIX39774
おまけ:Railsでの実装例
Ruby on Railsで実装するならこんな感じ。
# SELECT句のSQLを書く sql = <<~SQL 100.0 * SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END) / COUNT(*) AS good, 100.0 * SUM(CASE WHEN answer = 'ふつう' THEN 1 ELSE 0 END) / COUNT(*) AS fair, 100.0 * SUM(CASE WHEN answer = '悪かった' THEN 1 ELSE 0 END) / COUNT(*) AS bad SQL # SQLを実行して値を取得する survey = Survey.select(sql)[0] survey.good #=> 53.8461538 survey.fair #=> 30.7692308 survey.bad #=> 15.3846154補足説明
- 列の別名を日本語にするとプログラムとの相性が悪くなるので、ここではgood/fair/badとした
- 値のフォーマットはViewの責務なので、ここでは算出された値を純粋に返すだけにした
Survey.select(sql).first
とすると、ORDER BY句が自動的に追加されてSQLエラーが発生するので、あえて[0]
とした別解
本記事のコメント欄より。
AVG関数を使う
SELECT TO_CHAR( AVG(CASE WHEN answer = '良かった' THEN 100 ELSE 0 END), '999.9%' ) AS "良かった", TO_CHAR( AVG(CASE WHEN answer = 'ふつう' THEN 100 ELSE 0 END), '999.9%' ) AS "ふつう", TO_CHAR( AVG(CASE WHEN answer = '悪かった' THEN 100 ELSE 0 END), '999.9%' ) AS "悪かった" FROM surveys;(実行結果は上の本文と同じ)
列方向ではなく、行方向に平均値を出す
SELECT answer, TO_CHAR( 100.0 * COUNT(*) / (SELECT COUNT(*) FROM surveys), '999.9%' ) AS "rate" FROM surveys GROUP BY answer ORDER BY rate DESC;実行結果
answer rate 良かった 53.8% ふつう 30.8% 悪かった 15.4%
- 投稿日:2020-10-23T01:25:11+09:00
NameError: uninitialized constantを解決する【ActionMailer】
- 投稿日:2020-10-23T00:19:37+09:00
Rails 画像をスライドさせる 【Swiper】
やりたい事
よくあるホームページで、画像が自動でスライドしていくのがあると思います。
あれを今回「Swiper」を使い簡単に実装しようと思います。
SwiperはダウンロードとCDNがあるので今回はCDNの方で実装を行います。実装
こちらからコピーして読み込む。https://cdnjs.com/libraries/Swiper
https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.jshttps://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.cssCDNで読み込む例
<head> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.min.css"> </head> <body> 〜中略〜 <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.js"></script> </body>SwiperのHTMLの基本の記述
<div class="swiper-container"> <!-- メイン表示部分 --> <div class="swiper-wrapper"> <!-- 各スライド --> <div class="swiper-slide"><img src="/assets/01.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/02.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/03.jpg" alt style="width: 100%; height: 100%;"></div> </div> <!-- ナビケーション --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> <div class="swiper-pagination"></div> </div>CSSでサイズ調整
全体を囲う
<div class="swiper-container">
にCSSで調整する事で、スライダーをサイズを設定する。.swiper-container{ width: 1000px; height: 400px; }Swiperの基本設定のJavaScript記述
<script> var mySwiper = new Swiper('.swiper-container'); </script>これで一応、最低限の機能で動くスライダーの完成です。
ただし、本当に最低限の機能「イメージを左右にマウスなどでドラックすれば動く」という状態であり、左右の矢印ナビゲーションや、自動再生などは機能しない状態。Swiperのオプションを追加
オプションを追加していきます。オプション色々ありますが今回はこれでやります。
<script> var mySwiper = new Swiper ('.swiper-container', { loop: true, //画像のループ effect: 'slide', //切り替わるときのアニメーション speed: 3000, //画像の切替スピード autoplay: { //自動で動かす delay: 3000, disableOnInteraction: true }, pagination: { //ページネーション el: '.swiper-pagination', }, navigation: { //ナビケーション nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>実装完了
最終的に下記の様になります。
<!DOCTYPE html> <html> <head> <title>Mailers</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application' %> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.min.css"> </head> <body> <div class="swiper-container"> <!-- メイン表示部分 --> <div class="swiper-wrapper"> <!-- 各スライド --> <div class="swiper-slide"><img src="/assets/01.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/02.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/03.jpg" alt style="width: 100%; height: 100%;"></div> </div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> <div class="swiper-pagination"></div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.js"></script> <script> var mySwiper = new Swiper ('.swiper-container', { loop: true, //画像のループ effect: 'slide', //切り替わるときのアニメーション speed: 3000, //画像の切替スピード autoplay: { //自動で動かす delay: 3000, disableOnInteraction: true }, pagination: { //ページネーション el: '.swiper-pagination', }, navigation: { //ナビケーション nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script> </body> </html>おわり
お疲れ様でした。Railsであれば実装完了をコピペすれば動くはずです。
参考リンクにオプションの細かな内容が記載されていますので参考にしてみて下さい。
https://garigaricode.com/swiper/
- 投稿日:2020-10-23T00:19:37+09:00
Rails 画像を自動でスライドさせる 【Swiper】
やりたい事
よくあるホームページで、画像が自動でスライドしていくのがあると思います。
あれを今回「Swiper」を使い簡単に実装しようと思います。
SwiperはダウンロードとCDNがあるので今回はCDNの方で実装を行います。実装
こちらからコピーして読み込む。https://cdnjs.com/libraries/Swiper
https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.jshttps://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.cssCDNで読み込む例
<head> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.min.css"> </head> <body> 〜中略〜 <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.js"></script> </body>SwiperのHTMLの基本の記述
<div class="swiper-container"> <!-- メイン表示部分 --> <div class="swiper-wrapper"> <!-- 各スライド --> <div class="swiper-slide"><img src="/assets/01.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/02.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/03.jpg" alt style="width: 100%; height: 100%;"></div> </div> <!-- ナビケーション --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> <div class="swiper-pagination"></div> </div>CSSでサイズ調整
全体を囲う
<div class="swiper-container">
にCSSで調整する事で、スライダーをサイズを設定する。.swiper-container{ width: 1000px; height: 400px; }Swiperの基本設定のJavaScript記述
<script> var mySwiper = new Swiper('.swiper-container'); </script>これで一応、最低限の機能で動くスライダーの完成です。
ただし、本当に最低限の機能「イメージを左右にマウスなどでドラックすれば動く」という状態であり、左右の矢印ナビゲーションや、自動再生などは機能しない状態。Swiperのオプションを追加
オプションを追加していきます。オプション色々ありますが今回はこれでやります。
<script> var mySwiper = new Swiper ('.swiper-container', { loop: true, //画像のループ effect: 'slide', //切り替わるときのアニメーション speed: 3000, //画像の切替スピード autoplay: { //自動で動かす delay: 3000, disableOnInteraction: true }, pagination: { //ページネーション el: '.swiper-pagination', type: 'bullets', clickable: true }, navigation: { //ナビケーション nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>実装完了
最終的に下記の様になります。
<!DOCTYPE html> <html> <head> <title>Mailers</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application' %> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/css/swiper.min.css"> </head> <body> <div class="swiper-container"> <!-- メイン表示部分 --> <div class="swiper-wrapper"> <!-- 各スライド --> <div class="swiper-slide"><img src="/assets/01.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/02.jpg" alt style="width: 100%; height: 100%;"></div> <div class="swiper-slide"><img src="/assets/03.jpg" alt style="width: 100%; height: 100%;"></div> </div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> <div class="swiper-pagination"></div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/5.3.7/js/swiper.min.js"></script> <script> var mySwiper = new Swiper ('.swiper-container', { loop: true, //画像のループ effect: 'slide', //切り替わるときのアニメーション speed: 3000, //画像の切替スピード autoplay: { //自動で動かす delay: 3000, disableOnInteraction: true }, pagination: { //ページネーション el: '.swiper-pagination', type: 'bullets', clickable: true }, navigation: { //ナビケーション nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script> </body> </html>おわり
お疲れ様でした。Railsであれば実装完了をコピペすれば動くはずです。
参考リンクにオプションの細かな内容が記載されていますので参考にしてみて下さい。
https://garigaricode.com/swiper/
- 投稿日:2020-10-23T00:16:03+09:00
誤った情報をpushしてしまった時の対処法
この記事で分かること
- 誤った情報をpushしてしまった
- 誤った情報をcommitしてしまった
誤った情報をpushしてしまった
pushした情報をローカルリポジトリに戻すことはできません。したがって、pushする前に作業をしているブランチは正しいのかどうか、必ず確認するようにしましょう。
それでも間違ってpushしてしまうことがあります。ローカルリポジトリにその情報は戻せないものの、リモートリポジトリにある誤ったcommit情報は取り消すことができますcommitを取り消す方法
commitを取り消すためには、revertと呼ばれる技術を用います
間違ってpushしたcommitを取り消すことができます。commitを削除するのではなく、「指定するcommitを取り消すためのcommit」を追加で行います。
revertはcommitされた変更と逆になる変更を追加することで、commitを取り消します誤った情報をcommitしてしまった
現場からは以上です!
- 投稿日:2020-10-23T00:15:30+09:00
[Rails] find と find_by の違い
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
findとfind_byについて曖昧なところがあったので、自分なりにまとめてみました。find
- 引数にはid(主キー)を指定します。
- 指定したidのレコードを取得するというイメージです。
- idが見つからない時は例外(RecordNotFound)が返って来ます。赤いエラーページが発生してしまうのですね。
- 引数を複数指定することも可能です。
モデル名.find(idデータ)
- 具体的には以下のように使います。
Item.find(1) # => idが1のレコードを返す Item.find(1,3,5) # => 指定したidを配列で返すfind_by
- データは1番最初に合致した1件のみ取得できます。
- id以外のカラム名なども検索条件にできます。
- 条件に合致するものがないとnilを返します。取得データがなくてもfind_byの記述以降も処理を続けたい時に便利ですね。
- 条件は複数指定可能です。
モデル名.find_by(条件)
- 具体的には以下のように使います。
Article.find_by(title: 'hoge') # => titleが'hoge'で最初に合致したデータを返す Fruit.find_by(name: 'apple', color: 'red') # => nameが'apple'でcolorが'red'のデータを返す2つ条件を指定して1つだけ合致しなかった場合
Fruit.find_by(name: 'apple', color: 'blue') #=> nilを返す
- 投稿日:2020-10-23T00:15:30+09:00
find と find_by の違い
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
findとfind_byについて曖昧なところがあったので、自分なりにまとめてみました。find
- 引数にはid(主キー)を指定します。
- 指定したidのレコードを取得するというイメージです。
- idが見つからない時は例外(RecordNotFound)が返って来ます。赤いエラーページが発生してしまうのですね。
- 引数を複数指定することも可能です。
モデル名.find(idデータ)
- 具体的には以下のように使います。
Item.find(1) # => idが1のレコードを返す Item.find(1,3,5) # => 指定したidを配列で返すfind_by
- データは1番最初に合致した1件のみ取得できます。
- id以外のカラム名なども検索条件にできます。
- 条件に合致するものがないとnilを返します。取得データがなくてもfind_byの記述以降も処理を続けたい時に便利ですね。
- 条件は複数指定可能です。
モデル名.find_by(条件)
- 具体的には以下のように使います。
Article.find_by(title: 'hoge') # => titleが'hoge'で最初に合致したデータを返す Fruit.find_by(name: 'apple', color: 'red') # => nameが'apple'でcolorが'red'のデータを返す2つ条件を指定して1つだけ合致しなかった場合
Fruit.find_by(name: 'apple', color: 'blue') #=> nilを返す