- 投稿日:2020-06-01T22:28:46+09:00
メモ
偶数か奇数か
puts "数字入れて" n = gets.to_i if n.even? puts "偶数です" else n.odd? puts "奇数です" endto_i to_s
- to_iメソッドが文字→数値
- to_sメソッドが数値→文字
getsは文字列で保存する。
数値に変換するため→gets.to_ieach_with_index
fruits=[“りんご”, “メロン”, “イチゴ”] fruits.each_with_index do |fruit, i| puts “#{i+1}番目の要素は#{fruit}です。” end 【結果】 1番目の要素はりんごです。 2番目の要素はメロンです。 3番目の要素はイチゴです。
- 投稿日:2020-06-01T22:02:22+09:00
マイグレーション up, downメソッド
マイグレーション up, downメソッド
マイグレーションファイルで定義されるup, downメソッドについて考えていきます
テーブルの定義が書いてあるこんなマイグレーションファイルがあるとする
テーブルを定義
class CreateTasks < ActiveRecord::Migration[6.0] def change create_table :tasks do |t| t.string :name t.text :description t.timestamps end end endこのテーブルの :name属性に
30文字以内という文字制限をつけたい場合にどのようなマイグレーションファイルを作るか、というのが今日のテーマ普通に考えればこれでいい。
limit制約を付ける
class ChangeTasksNameLimit30 < ActiveRecord::Migration[6.0] def change change_column :tasks, :name, :string, limit: 30 end endテーブルには望み通りの制限を課すことができる。
ところが後日、やっぱりlimit: 30はなくそうという話になった。
そこでこんなコマンドを叩いてバージョンを一つ戻そうとすると...マイグレーションをロールバック
rails db:rollback # => not automatically reversible エラーが発生つまり定義されたマイグレーションファイルを自動的に戻すことができないよ
って怒られてしまう。何が起こったの??
Railsはchange_columnのバージョンを戻す処理をバージョンを上げる際のコードから自動生成できないため、こう言ったエラーが起こってします。
つまりRailsが「このマイグレーションファイルを消した後の元の姿がわからん!!」
って言ってエラーを吐き出します。どうするか?
upメソッドとdownメソッドを使う
ruby.rbclass ChangeTasksNameLimit30 < ActiveRecord::Migration[6.0] def up change_column :tasks, :name, :string, limit: 30 end def down change_column :tasks, :name, :string end endupメソッドは rails db:migrateのときの処理
downメソッドは rails db:rollbackのときの処理つまりバージョンを上げるときはupメソッドで処理をしてください。
下げるときはdownメソッドで処理をしてください。と伝えることで、rails db:rollbackをした時にアプリケーションがどんな処理をするべきかを
伝えることができるんですね。こうすることでnot automatically reversible エラーの発生も防ぐことができますし、コードをみた人がどんな処理をしたいかもわかりやすいということですね。めでたしめでたし。
本日はここまでです。
一人前のエンジニアになるまであと88日
- 投稿日:2020-06-01T18:52:50+09:00
【Rails5.2+Rspec/TDD】Rspecを導入して簡単にテストする手順(テスト駆動開発)
環境
ruby 2.6.4
Rails 5.2.4.1
rbenv 1.1.2
mysql2 0.5.3
やりたいこと
TDD(テスト駆動開発)をするためにRspecを使っていきます
Rspecを使う手順を簡単に説明している記事がそこまで多くないので自分用にメモしておきます
今回は簡単な導入方法を残しておきます
元記事:【Rails5.2/TDD】Rspecを超簡単に導入する簡単手順(テスト駆動開発)
カンタン導入手順
ステップ1. 新規アプリ作成
$ rails new sample_project --api -Tステップ2. TDD用にGem追加
Gemfilegroup :development, :test do gem 'rspec-rails', '~> 3.5' end group :test do gem 'factory_bot_rails', '~> 4.0' gem 'shoulda-matchers', '~> 3.1' gem 'faker' gem 'database_cleaner' endステップ3. gemインストール
$ bundle installステップ4. Rspecファイル生成
$ rails generate rspec:installステップ5. factoriesディレクトリ作成
$ mkdir spec/factoriesステップ6. rails_helper.rb修正
spec/rails_helper.rbrequire 'database_cleaner' # 追加 Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec with.library :rails end end # 追加 RSpec.configure do |config| # 追加 config.include FactoryBot::Syntax::Methods # 追加 config.before(:suite) do DatabaseCleaner.clean_with(:truncation) DatabaseCleaner.strategy = :transaction end # 追加 config.around(:each) do |example| DatabaseCleaner.cleaning do example.run end end今回は導入のみですが実際のテストで下の記事がとても参考になります
参考文献
- 投稿日:2020-06-01T18:50:55+09:00
【Rails5】[ Turbolinks ] ページ遷移やブラウザバックでJSが動かないときの対処法
実装した機能
開発環境
ruby > 2.6.5 rails > 5.2.4.2実装したJS
$(document).ready(function(){ $("#menu").on("click", function() { $(this).next().slideToggle(); }); });jqueryを使って、なんの変哲もない開閉式ハンバーガーメニューをつけました。
JSのコード自体の良し悪しはおいておいて、動作としては問題ないはずです。状況
初期ロード時には問題なく動作する。
ページ遷移、ブラウザバックのときに挙動がおかしい。
クリックで発火はしているが、開閉をループしたり、不安定。
リロードすると通常動作する。考察と対策
動いてはいるので、おそらく読み込みのタイミングが間違っている?
→ready
onload
ajaxStop
など一通り試してみてもダメ。グーグル先生に相談したら、こんな記述を発見
$(document).on('turbolinks:load', function () { ... });
turbolinks:load
なにこれ見たことない…
どうやらRails独自の記述らしいです。Turbolinksの扱い
こちらの記事を参考にさせていただきました。
turbolinksチートシートTurbolinksとは?
- Ajaxによるページ遷移の高速化のためのライブラリ(Gem)
- ユーザ側から見て、通常のページ遷移と同じように表示される/動作する
- Rails4からデフォルトでインストールされている
つまり、この機能が今回のJSに影響してしまっているようです。
turbolinksをどう扱うか
Gemなので、消してしまえば解消はできますが解決にはならないので
どう扱うべきかリサーチしてみました。主にこのような扱いがあります。
- <a>タグごとにturbolinksを無効にする
- turbolinks自体を無効化(削除)する
- JSの読み込み時にturbolinksを適応しない、タイミングを変える
1.<a>タグごとにturbolinksを無効にする
リンク自体に
{"turbolinks" => false}
を指定すると
そのリンクはturbolinksが無効になります。<%= link_to "HOGE", root_path, data: {"turbolinks" => false} %> <%# => <a data-turbolinks="false" href="/">HOGE</a> %>これを記述すれば、間違いなくturbolinksを外すことができます。
特定のスクリプトのみ制御する場合は良さそうですが、さすがに全部に記述するのは厳しそうですね…2.turbolinks自体を無効化(削除)する
Gemを削除
この一行を削除
Gemfile#gem 'turbolinks', '~> 5'
ターミナル$ bundle updateapplication.jsを編集
app/assets/javascripts/application.js//= require turbolinks #この行を削除
application.html.erbを編集
'data-turbolinks-track': 'reload'
を削除します。app/views/layouts/application.html.erb<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>これで無効化されました。
JSなどを多用するサイトでなければ無効化してしまうのが確実かもしれません。3.JSの読み込みにturbolinksを適応しない
ready
onload
などと同じように、
この記述でturbolinksを適応せずにロードできます。$(document).on('turbolinks:load', function () { ... });他にも、turbolinksを適応するタイミングも変更ができます。
詳しく知りたい方はこちらを参照ください。
その他のライフサイクルイベントをとるスクリプトごとに微調整が効くので、今回はこれが最適解だと思います。
まとめ
果たして、Turbolinksは優れた機能なのか、おせっかい機能なのか…
今の所どちらとも言えません笑
デフォルトでインストールされているということは、きっとあったほうが良いのだろうと思いますが…
もっと効果的な使用法をご存じの方はぜひコメントを下さい!
- 投稿日:2020-06-01T18:32:09+09:00
heroku に push しようとするとprecompiling assets failed. が起きてしまう件
環境
rails 5.2.3
Vs code基本的な解決法
多くの場合 config/application.rb
内に config.assets.initialize_on_precompile=false
の記述を加えればこの問題は解決される。これ以外の場合
RAILS_ENV=production bundle exec rake assets:precompile
を行いどのファイルが悪さをしているのかを調べる自分の場合 application.css の
@import="bulma";
が悪さをしており これを削除したところdeployがうまくった
(うまくいったがbulmaを消したためビューが崩れてしまった。)
- 投稿日:2020-06-01T18:19:18+09:00
app/assetsやアップロードされたS3上のファイルはCloudFrontで速度改善しよう
TL;DR
コンテンツの表示速度改善にはCDN配信が有効です。
【対応前】
【対応後】
はじめに
アプリケーションで使用するCSSやJavascript、デザインアイコン、アップロードした画像など同一ページ内にそれらが入り混じっていると表示にかなり時間がかかりますよね。lazyloadやCache-Controlをしているけどさらに全体最適を考えている方はCDN配信を利用してみるのは如何でしょうか。
今回は詰まった箇所をまとめていくので以下の部分は省略します。
- S3バケットの作成方法
- Carrierwaveの初期設定
- CloudFrontの作成方法
作成方法などは丁寧な記事がたくさんあるのでそちらを確認したほうがわかりやすいです。
S3バケットの作成、Carrierwaveの接続設定、CloudFrontの作成は済んでいる前提で進めていきます。CloudFrontの設定
config/initializer/carrierwave.rbconfig.asset_host = 'https://d3if231hoge.cloudfront.net'
https://
を付け忘れるとエラーになります。config/environments/production.rbconfig.assets.compile = true config.action_controller.asset_host = '//d3if231hoge.cloudfront.net'
compile=false
だとエラーになるようです。ActionView::Template::Error(The asset "d1234.cloudfront.net/../hoge.png" is not present in the asset pipeline.app/assets/
上記、各自作成したhostを設定後に
bundle exec rake assets:precompile
を実行するとapp/assets
にあるファイルは自動的にS3に配置されます。
表示する際はasset_pathで指定。相対パスではなくファイル名指定。= image_tag asset_path('hoge.png')Heroku運用している場合は、デプロイ時に自動でプリコンパイルしたいと思います。
その場合はheroku.ymlのrelease
ブロックに追記すると自動プリコンパイルしてくれます。heroku.ymlrelease: command: - rake assets:precompileapp/assets/以外のS3配置のファイル
アプリケーション経由でS3に直接配置されたファイルはassets:precompileの対象外です。(考えてみたら当然なのですが、S3のassets配下に画像設置しているのにプリコンパイルされない!みたいなよくわからない思考になっていた時がありました..)
おわりに
app/assets周りの画像を多用しているページでCDN対応ができると、GoogleのPageSpeed Insightsで10ポイントほど上がりました。
- 投稿日:2020-06-01T15:43:21+09:00
metaを用いたページの自動遷移メモ(デプロイ後URL有)
3秒後に、指定のリンク先のURLに自動遷移させたい場合は下記の様なコードを記述する。
htmlファイル%meta{content: "3;URL=指定のリンク先のURL", "http-equiv": "REFRESH"}
- 投稿日:2020-06-01T14:02:58+09:00
has-oneとhas_manyの違いについて、まとめてみる
はじめに
railsしっかり勉強し始めて、半年くらいたちます。(多分)
最近学んだこと多いので、アウトプットしていきますー。
ちょっと説明下手だったり、間違ってたりする部分あるかもしれないので、ご了承ください!!has_oneとhas_manyって?
両方とも、モデルの関係定義に使われるものです。
has_one
とは、1つのモデル(親)に対して、1つのモデル(子)を持つこと(1対1の関係を持つ)ができるということを定義する場合に使います。
例:)1つの投稿に対して、画像を1枚添付することができる。
has_many
とは1つのモデル(親)に対して、たくさんの同じモデル(子)を持つこと(1対多の関係を持つ)ができることを定義する場合に使います。
例:)1つの投稿に対して、画像を複数枚添付することができる。違いについて
has_one
やhas_many
で関連づけられたモデルを親と関連づけて作成したい場合、それぞれ作成方法が異なるので、気をつけましょう!実際のコードを見てみる
画像.rbclass Image < ApplicationRecord mount_uploader :image, ImageUploader belongs_to :tweet_image, foreign_key: :tweet_id, optional: true #optional: trueをつけることによって、外部キーがなくても、保存できる endモデル.rbclass TweetImage < Tweet validates :content, presence: true, length: { maximum: 140 } belongs_to :user has_one :image, foreign_key: :tweet_id accepts_nested_attributes_for :image, allow_destroy: true endここのコードだと、
accepts_nested_attributes_for :image
を使って、TweetImage
を保存する時、同時に子モデルのImage
を保存するので、Image
モデルのファイルにoptional: true
をつけて、外部キーが存在しなくても保存できるようにしておくことが必要です。class TweetsController < ApplicationController before_action :authenticate_user! def new @tweet = TweetImage.new @tweet.build_image #has_oneの関係の場合 endclass TweetsController < ApplicationController before_action :authenticate_user! def new @tweet = TweetImage.new @tweet.images.build #has_manyの関係の場合 end上記は私が、制作物を作った際につかっているコードです。
関係性を図で表すとこんな感じです。TweetとTweetImageはSTIを使った継承関係で、
TweetImageはhas_one
で画像(Imageモデル)を持っています。
コントローラはTweetのコントローラのみで管理しているので、画像を添付する場合のために必ずはじめはTweetImageである必要がありました。(accepts_nested_attributes_forを利用しているため、Formの部分に画像添付の部分を出せなくなってしまうため。)newでモデルを作ることもできますが、IDを1回ごとに渡さないといけないので、少し面倒です。
build
を使うと、自動でIDを入れてくれるので、簡潔にコードを書くことができます。最後に
説明が物足りてないところがありますが、ここで終わります!
ここ違うよってとこありましたら、コメントでご指摘お願いします!!
- 投稿日:2020-06-01T11:32:21+09:00
【Rails】マイグレーションコマンドまとめ
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalinaマイグレーションコマンドの書き方
$ rails g migration ChangeColumnToBooks
は、
$ rails generation migration change_column_to_books
と書くのと同じ。つまり、
generation
はg
と略す事ができ、
AddBodyToBooks
の様に、単語の先頭を大文字にする事で「 _ 」を書く手間が省ける。基本コマンド
1.モデルとテーブルを作成
$ rails g model モデル名 カラム名:型名
ターミナル$ rails g model Book title:stringmigrate/~_create_books.rbclass CreateBooks < ActiveRecord::Migration[5.2] def change create_table :books do |t| t.string :title t.timestamps end end end2.モデルとテーブルを削除
rails d model モデル名
ターミナル$ rails d model Book3.マイグレーションを実行
ターミナル$ rails db:migrate4.マイグレーションの内容を戻す
①1ステップ前に戻る場合
ターミナル$ rails db:rollback①複数ステップ前に戻る場合
ターミナル$ rails db:rollback STEP=5 # 数字は自由に変更可能4.マイグレーションのステータス確認
ターミナルrails db:migrate:status
テーブル関係
1.テーブルのみを削除
$ rails g migration Dropテーブル名
ターミナル$ rails g migration DropBooksmigrate/~_drop_books.rbclass DropBooks < ActiveRecord::Migration[5.2] def change drop_table :books # 追記 end end2.テーブル名を変更
$ rails g migration Rename変更前のテーブル名To変更後のテーブル名
ターミナル$ rails g migration RenameBooksToArticlesmigrate/~_rename_books_to_articles.rbclass RenameBooksToArticles < ActiveRecord::Migration[5.2] def change rename_table :books, :articles # 追記 end endカラム関係
1.カラムを追加
①単体
$ rails g migration Addカラム名Toテーブル名 カラム名:型名
ターミナル$ rails g migration AddBodyToBooks body:textmigrate/~_add_body_to_books.rbclass AddBodyToBooks < ActiveRecord::Migration[5.2] def change add_column :books, :body, :text end end②複数
$ rails g migration AddColumnsToテーブル名 カラム名:型名 カラム名:型名 カラム名:型名
ターミナル$ rails g migration AddColumnsToBooks body:text introduction:text price:integermigrate/~_add_columns_to_books.rbclass AddColumnsToBooks < ActiveRecord::Migration[5.2] def change add_column :books, :body, :text add_column :books, :introduction, :text add_column :books, :price, :integer end end2.カラムを削除
①単体
$ rails g migration Removeカラム名Fromテーブル名 カラム名:型名
ターミナル$ rails g migration RemoveTitleFromBooks title:stringmigrate/~_remove_title_from_books.rbclass RemoveTitleFromBooks < ActiveRecord::Migration[5.2] def change remove_column :books, :title, :string end end②複数
$ rails g migration RemoveColumnsFromテーブル名 カラム名:型名 カラム名:型名 カラム名:型名
ターミナル$ rails g migration RemoveColumnsFromBooks body:text introduction:text price:integermigrate/~_remove_columns_from_books.rbclass RemoveColumnsFromBooks < ActiveRecord::Migration[5.2] def change remove_column :books, :body, :text remove_column :books, :introduction, :text remove_column :books, :price, :integer end end3.カラムのデータ型を変更
$ rails g migration ChangeDataカラム名Toテーブル名 カラム名:型名
ターミナル$ rails g migration ChangeDataTitleToBooksmigrate/~_change_data_title_to_books.rbclass ChangeDataTitleToBooks < ActiveRecord::Migration[5.2] def change change_column :books, :title, :text # 追記 end end4.カラムのオプションを追加
$ rails g migration ChangeOptionカラム名Toテーブル名 カラム名:型名
ターミナル$ rails g migration ChangeOptionTitleToBooksmigrate/~_change_option_title_to_books.rbclass ChangeOptionTitleToBook < ActiveRecord::Migration[5.2] def change change_column :books, :title, :string, null: false # 追記 end end5.データ型一覧
型名 役割 string 短い文字列 text 長い文字列 integer 整数 float 浮動少数 decimal 精度の高い少数 datetime 日時 timestamp タイムスタンプ time 時間 date 日付 binary バイナリ文字列 boolean 真偽値 6.よく使うオプション
オプション名 役割 default 初期値を設定 null 空欄の真偽 limit 長さを制限 unique 一意制約を付与 unique インデックスを付与
- 投稿日:2020-06-01T10:46:25+09:00
【リファクタリング】ルーティングの書き方
概要
ルーティングをスッキリ書く方法です
背景
ルーティングの指定をする際、7つのアクションのうち6つを使用する場合、onlyで書いたらダラダラと長くなってしまって、個人的に自分ダサっっとなったので備忘録として残しますRailsの7つのアクション
まずは、Railsの7つのアクションについておさらい
Action 役割 index 一覧を表示する new 追加する create 追加内容を登録す edit 編集する update 編集内容を更新する destroy 削除する show 個別内容を表示する 書き方
ここでは「tweets」というリソースにルーティングを行います
7つのアクション全てを実装する場合
routes.rbresources :tweets使用するアクションを限定する場合
ここでは「index」「new」「create」を使用することとします
routes.rbresources :tweets, only: [:index, :new, :create]不要なアクションを削除する場合
ここでは「show」以外のアクションを使用することとします
routes.rbresources :tweets, except: [:show]まとめ
ついつい、onlyで記入しがちですが、exceptを使用することでコードがスッキリし読みやすくなります
私もスッキリを心掛けてまいります参考
- 投稿日:2020-06-01T09:58:10+09:00
メディアクエリ
レスポンシブWebデザインのメディアクエリについてのメモ
cssファイルやscssファイル内にてメディアクエリを指定することで、
タブレットやスマートフォン、または規定外の大画面にも対応できる様なcssを作成できる。
width等でのcssが切り替わる境目をブレイクポイントと呼ぶ。
ブレイクポイントは実際のビューが崩れそうなタイミングをとっても良いが、特に何もなければ、
1170pxと670px付近でブレイクポイントを取ると良い。scssファイル@media (min-width: 1170px { h1 { color: pink; } } @media (min-width: 670px { h1 { color:white; } } @media (max-width 670px { h1 { color: blue; } }別件だが、width: 25%; を4つ並べてビュー崩れが起こる場合は、
borderやpaddingも含まれているため、box-sizing: border-box;を与えてやると直る。
これは全てに与えてやることが推奨されている。scssファイル* { box-sizing: border-box; }
- 投稿日:2020-06-01T09:32:18+09:00
Vagrant+Docker+Rails+Nuxt.js+MySQL+SSL化
はじめに
ポートフォリオ作成まで、環境構築が辛すぎたのでその過程を書きました。
完全に全ての技術に対して初心者だったので、毎日絶望していました。ポートフォリオのために快適な開発環境をまず作りたくて試行錯誤していました。
Docker for Macが重すぎ、しかもfrontendとbackendに分けて、
しかもNginxを使ってSSL化までする記事がなさすぎて絶望したので実験しながら作りました。今後忘れないために備忘録として・・・。
とりあえずそれぞれHello World出来るまで。こんな人へ
とりあえずサクサクっと開発環境をつくりたいぜ。
Dockerとかの知識はちょっとあるぜ。これを読むとわかること/おおまかな流れ
- Vagrant環境構築
- Nuxt.js環境構築
- Docker環境構築
- nuxtとRails(APIモード)とMySQLの開発環境構築
- Nginxの環境構築
- SSL化(オレオレ証明書)
環境
Mac OS
ruby:2.6.3
Rails 5.2.4.3フォルダ構成
app ├─docker-compose.yml ├─mutagen.yml ├─Vagrantfile ├─back #Rails | ├─Dockerfile | ├─Gemfile | └─Gemfile.lock ├─front #Nuxst.js | └─Dockerfile ├─nginx #nginx | └─nginx.conf └─ssl #nginxに読み込ませる鍵 ├─server.crt ├─server.csr └─server.keyVagrant
おおまかな流れ
- VirtualBoxをinstall
- Vagrantをinstall
- Vagrantfile作成
- Mutagenをinstall
- VagrantにSSH接続する
Vagrant/Virtualboxダウンロード
https://www.vagrantup.com/
https://www.virtualbox.org/brew cask install virtualboxbrew cask install vagrantVagrantBox
VagrantBox(OS)のダウンロード
今回はubuntuで構築します。
vagrant box add ubuntu/xenial64
vagrant box list #確認しておきましょう
Vagrant plugin
vagrant plugin install vagrant-disksize vagrant-hostsupdater vagrant-mutagen vagrant-docker-composeVagrantセットアップ
作業フォルダの作成(名前はなんでも)
mkdir app cd appVagrantfileの作成
/appvagrant init ubuntu/xenial64
Vagrantfileを以下の内容に書き換えてください。
/app/VagrantfileVagrant.configure('2') do |config| config.vm.box = 'ubuntu/xenial64' config.vm.hostname = 'app' #任意のホストネーム config.vm.network :private_network, ip: '192.168.50.10' #ここがVagrant内にアクセスするIP config.vm.provider :virtualbox do |vb| vb.gui = false vb.cpus = 4 #割り当てるCPUコア数 vb.memory = 4096 #割り当てるメモリ vb.customize ['modifyvm', :id, '--natdnsproxy1', 'off'] vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'off'] end config.disksize.size = '30GB' #ディスクサイズ config.mutagen.orchestrate = true config.vm.synced_folder './', '/home/vagrant/app', type: "rsync", rsync_auto: true, rsync__exclude: ['.git/', 'node_modules/', 'log/', 'tmp/'] config.vm.provision :docker, run: 'always' config.vm.provision :docker_compose endMutagenのInstall
ファイル同期ソフトであるmutagenのインストールをします。
https://mutagen.io/brew install mutagen-io/mutagen/mutagen/apptouch mutagen.yml vim mutagen.yml
/app/mutagen.ymlsync: app: mode: "two-way-resolved" alpha: "./" beta: "app:/home/vagrant/app" #同期させるフォルダ/Vagrantfileで設定したホストネームと合わせてください。 ignore: vcs: true paths: - "/node_modules" - "/log" - "/tmp"Vagrant起動
/appvagrant up
はじめてVirtualBoxを入れたタイミングで「セキュリティとプライバシー」で弾かれるそうなのでダウンロードしたアプリケーションの許可をして再度upしてください。
: No such file or directory @ rb_sysopen - /Users/hoge/.ssh/config (Errno::ENOENT)
また、こんな感じのエラーが出たら、
touch /Users/hoge/.ssh/config.ssh/configを作成してあげましょう。
仮想環境にssh接続
vagrant sshWelcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-179-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage * MicroK8s passes 9 million downloads. Thank you to all our contributors! https://microk8s.io/ 2 packages can be updated. 0 updates are security updates. New release '18.04.4 LTS' available. Run 'do-release-upgrade' to upgrade to it. Last login: Sat May 30 12:32:45 2020 from 10.0.2.2
こんな感じのログが出るとSSH接続完了です。
ちなみに
vagrant haltも覚えておくと良いです。
同期されてねー!とか思ったらやります。vagrant環境の破棄です。(Vagrantfileが有る限りupで再度作成できるので安心)参考記事
Docker For Macが遅い:対策の実験
Vagrantを使う「Mac最速のDocker環境」を初心者向けに解説【遅いMac for Dockerを卒業】
vagrantとDockerで環境構築をした
Docker for MacからVagrant + CoreOSに切り替えたDocker
Dockerfile
/front/DockerfileFROM node:12.5.0-alpine ENV HOME="/app" \ LANG=C.UTF-8 \ TZ=Asia/Tokyo WORKDIR ${HOME} RUN apk update && \ apk upgrade && \ npm install -g n && \ yarn install &&\ rm -rf /var/cache/apk/* s ENV HOST 0.0.0.0おそらく最低限の構成(もっとシンプルにできたら教えてください。)
npmとyarnをinstallしてます。VagrantなのでIPをバインディング
以下参照
rails s -b 0.0.0.0 のオプション-bの意味/バインディングアドレスとは/back/DockerfileFROM ruby:2.6.3-alpine3.10 #おまじない的 ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata mysql-dev mysql-client yarn" \ DEV_PACKAGES="build-base curl-dev" \ HOME="/app" \ LANG=C.UTF-8 \ TZ=Asia/Tokyo WORKDIR ${HOME} #ワークスペースの確保 ADD Gemfile ${HOME}/Gemfile #GemfileをDocker内にコピー ADD Gemfile.lock ${HOME}/Gemfile.lock #Gemfile.lockをDocker内にコピー RUN apk update && \ apk upgrade && \ apk add --update --no-cache ${RUNTIME_PACKAGES} && \ apk add --update --virtual build-dependencies --no-cache ${DEV_PACKAGES} && \ bundle install -j4 && \ apk del build-dependencies && \ rm -rf /usr/local/bundle/cache/* \ /usr/local/share/.cache/* \ /var/cache/* \ /tmp/* \ /usr/lib/mysqld* \ /usr/bin/mysql* ADD . ${HOME}ところどころわからないところがありますが・・・。ご存知の方コメントくださると有り難いです。
/app/docker-compose.ymlversion: "3" services: db: image: mysql:5.7 env_file: - ./back/environments/db.env restart: always volumes: - db-data:/var/lib/mysql:cached back: build: back/ command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" env_file: - ./back/environments/db.env volumes: - ./back:/app:cached depends_on: - db ports: - 3000:3000 front: build: front/ command: yarn run dev volumes: - ./front:/app:cached ports: - 8080:3000 depends_on: - back nginx: image: nginx ports: - 443:443 volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./ssl/server.crt:/etc/nginx/ssl/server.crt - ./ssl/server.key:/etc/nginx/ssl/server.key volumes: public-data: tmp-data: log-data: db-data:Gemfile
/app/back/Gemfilesource 'https://rubygems.org' gem 'rails', '~>5'/app/backtouch Gemfile.lock
docker-composeを使ってbuild
vagrant内/appdocker-compose build
Nuxt.js
/app$ docker-compose run --rm front npx create-nuxt-app ? Project name --> sample # アプリ名 ? Project description --> sample # アプリの説明 ? Author name --> me # アプリの作成者 ? Choose the package manager --> Npm ? Choose UI framework --> None ? Choose custom server framework --> None ? Choose Nuxt.js modules --> Axios ? Choose linting tools --> - ? Choose test framework --> None ? Choose rendering mode --> Universal (SSR)Vagrant内/appdocker-compose up front
http://192.168.50.10:8080
にアクセスしてHello World!参考記事
Nuxt.js + Rails(API) on DockerのHello Worldするべ!
Rails
今回のRailsはAPIモードで作成するので、
--api
引数をば/appdocker-compose run --rm back rails new . -f -d mysql --api
back/config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %> host: db development: <<: *default database: webapp_development test: <<: *default database: webapp_testDBの環境変数のファイルを作ります。
/app/backmkdir environments
/app/back/environmentsvim db.env
/app/back/environments/db.envMYSQL_ROOT_PASSWORD=rootpassword MYSQL_USER=username MYSQL_PASSWORD=userpassword
DB権限設定をするためのSQLを作ります。
/app/back/dbvim grant_user.sql
grant_user.sqlGRANT ALL PRIVILEGES ON *.* TO 'username'@'%'; FLUSH PRIVILEGES;DBへクエリを流し込む
Vagrant内/appdocker-compose build docker-compose up
Vagrant内/appdocker-compose ps
ちゃんとDBが動いている状態を確認
Vagrant内/appdocker-compose exec db mysql -u root -p -e"$(cat back/db/grant_user.sql)"先ほど設定した
rootpassword
を入力Vagrant内/appdocker-compose exec db mysql -u username -p -e"show grants;"権限の確認
先ほど設定したuserpassword
を入力+------------------------------------------------+ | Grants for user_name@% | +------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' | +------------------------------------------------+こうなればOK
Vagrant内/appdocker-compose exec app rails db:create
http://192.168.50.10:3000
にアクセスしてHello World!参考記事
Docker + Rails + Puma + Nginx + MySQL
Nginx
app/nginx/nginx.confworker_processes auto; events { worker_connections 1024; } http { server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/server.crt; #SSL証明書 ssl_certificate_key /etc/nginx/ssl/server.key; #秘密鍵 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location /api/ { proxy_pass http://192.168.50.10:3000; proxy_buffering off; } location / { proxy_pass http://192.168.50.10:8091; proxy_buffering off; } } }オレオレ証明書の作成
app/#秘密鍵の作成 sudo openssl genrsa -out app/ssl/server.key 2048 #CSR(証明書署名要求)の作成 sudo openssl req -new -key app/ssl/server.key -out app/ssl/server.csr #CRT(SSLサーバ証明書)の作成 sudo openssl x509 -days 3650 -req -signkey app/ssl/server.key -in app/ssl/server.csr -out app/ssl/server.crtVagrant内/appdocker-conpose up
https://192.168.50.10:8080
にアクセスしてHello World!Chromeで警告が出る場合
自分で発行したサーバー証明書(オレオレ証明書)をブラウザに登録する方法
こちらを参考に、ブラウザに証明書を登録してください。参考記事
最後に
かなり駆け足・長文になってしまい申し訳ありません。
読んでくださってありがとうございます。
とりあえずの備忘録として書きましたので、間違っていたらコメントで教えていただけると有り難いです。Vagrant環境内で、Nuxt.jsとRails、しかもDockerで構築してNginxでリッスン、しかもSSL化とかいう記事は無くて
それぞれの記事をつなぎ合わせてようやく完成しました。Docker、Vagrant、Nginx、Rails、Nuxt.jsに関しては完全に初心者です。
初めて作成するにはかなり無謀なチャレンジでした・・・。優しいマサカリ投げていただけると嬉しいです。
- 投稿日:2020-06-01T08:54:17+09:00
【Rails】gretelを使ってパンくずリストを追加してみる。
パンくずリストとは
パンくずリストとはWEBサイト上で自分がどこにいるかをわかりやすく表示しているものになります。
下記サイト参考
https://www.asobou.co.jp/blog/web/breadcrumb-listパンくずリストを導入することで
・ユーザビリティが高くなる
・SEOに強くなる
というメリットがあります。今回はrailsにてパンくずリストを導入する手順を書いていきます。
導入
railsでパンくずを導入するには「gretel」というgemを使うと便利です。
■gem gretelのGithub
https://github.com/lassebunk/gretelまずはGemfileに追記して、bundle installを行う。
Gemfile
gem 'gretel'$ bundle installその後起動コマンドを入力
$ rails generate gretel:installこのコマンドを入力すると、config配下にbreadcrumb.rbというファイルが生成されます。
そのファイルにパンくずの定義を書いていきます。書き方の例を下記に示します。
breadcrumbs.rbcrumb :admin_dashboard do link '<i class="fa fa-dashboard"></i> Home'.html_safe, admin_dashboard_path end crumb :edit_admin_site do link '設定', edit_admin_site_path parent :admin_dashboard end crumb :admin_users do link 'ユーザー', admin_users_path parent :admin_dashboard endcrumb crumsの名前を指定 do link '表示させたい文字', その文字のリンク先 parent 親の指定 endといった使い方になります。
ビュー側の表示は下記のように指定します。
<% breadcrumb :admin_users %>slimの場合は
- breadcrumb :admin_users参考
■パンくずリストについて参考にしたサイト
https://www.asobou.co.jp/blog/web/breadcrumb-list■gem gretelのGithub
https://github.com/lassebunk/gretel
- 投稿日:2020-06-01T05:05:37+09:00
rails active_storage: install実行時に追加されるテーブルについて
active_storage使用時に作成されるテーブルとカラムの役割について自分なりにまとめてみました
参考
https://railsguides.jp/active_storage_overview.html
環境
- Rails 5.2.4
- PostgreSQL
- Tweetモデルにactive_storageでtweet_imageを追加したとする
- 同様に、Userモデルにprofile_imageを追加
$ rails dbconsole
を使ってDBの中身を見ていきますselect * from Tweet id | content | created_at | updated_at ----+---------+----------------------------+---------------------------- 1 | first | 2020-05-31 09:15:39.315909 | 2020-05-31 09:15:39.34726 2 | second | 2020-05-31 09:41:35.573983 | 2020-05-31 09:42:03.209896各テーブルについて
active_storage_blobs
画像データを保存するためのテーブル
select * from active_storage_blobs; id | key | filename | content_type | metadata | byte_size | checksum | created_at ----+--------------------------+-----------------------------------------------------+--------------+-------------------------------------+-----------+--------------------------+---------------------------- 1 | g8VoNYkesyKi779tsSdQ2q2W | first_image.jpg | image/jpeg | {"identified":true,"analyzed":true} | 8237 | zcwCqc6RTr8QFI4elbnF+w== | 2020-05-31 09:15:39.270823 2 | uzRSGT69i5cNhoWDdoQ2gu8C | second_image.jpg | image/jpeg | {"identified":true,"analyzed":true} | 2481215 | m5LFOmNS4v3ddFGrtN/byA== | 2020-05-31 09:42:03.191085 3 | 9o2qkgbC77MixCiYKc3thCdx | user_image.jpg | image/png | {"identified":true,"analyzed":true} | 254885 | 0+RUqCki1Yn4sZB1ZjpJCw== | 2020-05-31 19:02:28.999065active_storage_attachment
使うモデルのクラス名を保存するポリモーフィックjoinテーブル
select * from active_storage_attachments; id | name | record_type | record_id | blob_id | created_at ----+--------------+-------------+-----------+---------+---------------------------- 1 | tweet_image | Tweet | 1 | 1 | 2020-05-31 09:15:39.324196 2 | tweet_image | Tweet | 2 | 2 | 2020-05-31 09:42:03.199872 3 | profile_image| User | 1 | 3 | 2020-05-31 19:02:29.025411
- name
- 紐づけるモデルの画像用カラム
- record_type
- 紐づけるモデル名
- record_id
- record_typeのモデルのid
- blob_id
- active_storage_blobsに保存された画像のid
name
,record_type
,record_id
でモデルと画像カラムを決めて、blob_id
で画像を紐づけることで一意な画像投稿機能ができると考えています最後に
おかしい部分があればご指摘いただけると嬉しいです!
- 投稿日:2020-06-01T00:31:37+09:00
【Rails5.2】RESTful APIをRailsで簡単に実装する手順(APIモード)
環境
ruby 2.6.4
Rails 5.2.4.1
rbenv 1.1.2
mysql2 0.5.3
やりたいこと
APIモードで簡単なtodoアプリを実装します
RESTfulなAPIをRailsで実装する手順を書いていきます
わかりやすさを追求して書いていきます
元記事:【Rails5.2】RESTful APIをRuby on Railsで実装する簡単手順(APIモード)
カンタン実装手順
ステップ1. APIモードで新規アプリを作成
$ rails new sample_app --api -Tステップ2. TDD(テスト駆動開発)用にGem追加
Gemfilegroup :development, :test do gem 'rspec-rails', '~> 3.5' end group :test do gem 'factory_bot_rails', '~> 4.0' gem 'shoulda-matchers', '~> 3.1' gem 'faker' gem 'database_cleaner' endステップ3. gemインストール
$ bundle installステップ4. Rspecファイル生成
$ rails generate rspec:installステップ5. factories作成
$ mkdir spec/factoriesステップ6. rails_helper.rb修正
spec/rails_helper.rbrequire 'database_cleaner' # 追加 Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec with.library :rails end end # 追加 RSpec.configure do |config| # 追加 config.include FactoryBot::Syntax::Methods # 追加 config.before(:suite) do DatabaseCleaner.clean_with(:truncation) DatabaseCleaner.strategy = :transaction end # 追加 config.around(:each) do |example| DatabaseCleaner.cleaning do example.run end end今回は導入部分だけですがapiモードで開発する際に参考になればと思います
参考文献