正規表現の使い方
正規表現の使い方
正規表現で便利なものや、使い方が複雑なものを備忘録としてまとめます。
キャプチャグループ
[1] pry(main)> '123456789'.gsub(/^(\d{3}).*(\d{5})$/, '\1\2') => "12356789" # キャプチャ: ()で括るとその部分がキャプチャされ、キャプチャされたものは最初から順に1から番号が割り当てられ、 第二引数にその番号を上記のように記載するとキャプチャされた部分だけを取得できる。 # グループ化: ()で括るとその部分がグループ化され、グループ化された部分が1つの塊として認識される。 その塊の後に[+]などを使用すると、塊で始まりそれ以降の任意の文字が[+]部分として許容されるようになる。 下記がそのイメージ検証 # つまり()で括るとキャプチャとグループ化の2つが行われる! [1] pry(main)> 'abcabcabc'.gsub(/^(abc)/, 'z') => "zabcabc" [2] pry(main)> 'abcabcabc'.gsub(/^abc/, 'z') => "zabcabc" [3] pry(main)> 'abcabcabc'.gsub(/abc/, 'z') => "zzz" [4] pry(main)> 'abcabcabc'.gsub(/(abc)/, 'z') => "zzz" [5] pry(main)> 'abcabcabc'.gsub(/(abc)+/, 'z') => "z" [6] pry(main)> 'abcabcabc'.gsub(/abc+/, 'z') => "zzz"
参考記事
今日からはじめよう、正規表現 in Ruby (()を使おう(キャプチャ・グループ化)編) - woshidan's blog
nextメソッドの使い方
nextメソッドの使い方
nextメソッドの動作の認識が誤っていたので、こちらに備忘録としてまとめます。
next使うと、その要素のままでそれ以降の処理がスキップされて次の要素に移ると思っていたが、
その際は、nilになってしまう。。。
そして、returnのようにnextにも引数が使えると知った。
[1, 2].map do |value| next if value == 1 value * 2 end →[nil, 4]
[1, 2].map do |value| next 1 if value == 1 value * 2 end →[1, 4]
よくよく考えたら、map
メソッドで要素をループしており、ブロックの中での処理結果を新しい配列の要素とするからnext if value == 1
がtrueになるとnext
メソッドに返り値を指定していないので、nilになる。。。。
可読性の高いクリーンなコード記載方法
可読性の高いクリーンなコード記載方法
現場で1年弱働いて、可読性の高いクリーンなコード記載を学んだので、備忘録としてこちらにまとめます。
三項演算子を利用して変数に値を設定
food = 'fruit' food == 'fruit' ? select_food_type = 'フルーツ' : select_food_type = 'フルーツ以外' ↓ food = 'fruit' select_food_type = food == 'fruit' ? 'フルーツ' : 'フルーツ以外' # 上記で変数foodに[fruit]が格納されていれば、select_food_typeには[フルーツ]そうでなければ[フルーツ以外]が格納される
また、3項演算子の結果がboolean値で、そのboolean値を変数に格納したい場合は、以下のように書ける
food = 'fruit' is_fruit = food == 'fruit' # 上記で変数foodに[fruit]が格納されていれば、is_fruitには[true]そうでなければ[false]が格納される
同じ変数を比較する際は、case文を利用
def fruit_type(fruit) return 'りんご' if fruit == 'apple' return 'オレンジ' if fruit == 'orange' return 'もも' if fruit == 'peach' end や def fruit_type(fruit) if fruit == 'apple' 'りんご' if fruit == 'orange' 'オレンジ' if fruit == 'peach' 'もも' end end ↓ def fruit_type(fruit) case fruit when 'apple' 'りんご' when 'orange' 'オレンジ' when 'peach' 'もも' end end
2つの変数の組み合わせで返り値を返す際にcase文を利用
def like_tuna_and_salmon(is_like_tuna, is_like_salmon) case [is_like_tuna, is_like_salmon] when [true, true] 'マグロもサーモンも好き' when [true, false] 'マグロは好きだが、サーモンは嫌い' when [false, true] 'マグロは嫌いだが、サーモンは好き' when [false, false] 'マグロもサーモンも嫌い' end end # 上記のように配列を使うことで、2つの変数の組み合わせを表せる
if文のネストを浅くするための[早期リターン]や[ガード節]という記法
def number_division_judge(number) if number.negative? 'マイナスの値です。' else if number < 100 '100未満の値です。' else '100以上の値です。' end end end ↓ def number_division_judge(number) return 'マイナスの値です。' if number.negative? if number < 100 '100未満の値です。' else '100以上の値です。' end end や def number_division_judge(number) return 'マイナスの値です。' if number.negative? number < 100 ? '100未満の値です。' : '100以上の値です。' end
2次配列の要素を複数の変数に1度で代入する方法
[16] pry(main)> x, y = [1, 2, 3, 4, 5, 6, 7, 8, 9].partition { |number| number & 3 == 0 } => [[4, 8], [1, 2, 3, 5, 6, 7, 9]] [17] pry(main)> x => [4, 8] [18] pry(main)> y => [1, 2, 3, 5, 6, 7, 9]
スプレッド構文を使うと配列の要素が配列になっていてもflattenを使ったのと同じ状態にできる
[1] pry(main)> [ [2] pry(main)* 'a', [3] pry(main)* 'b:cde'.scan(/(?<=:).*/), [4] pry(main)* ] => ["a", ["cde"]] [5] pry(main)> [ [6] pry(main)* 'a', [7] pry(main)* *'b:cde'.scan(/(?<=:).*/), [8] pry(main)* ] => ["a", "cde"] [9] pry(main)> [ [10] pry(main)* 'a', [11] pry(main)* *['cde'], [12] pry(main)* ] => ["a", "cde"]
変数の中身がStringであるものの同士の足し算は、行わない方が良い
[1] pry(main)> a = 'a' => "a" [2] pry(main)> b = 'b' => "b" [3] pry(main)> c = a + b => "ab" [4] pry(main)> a = nil => nil [5] pry(main)> c = a + b NoMethodError: undefined method `+' for nil:NilClass from (pry):40:in `__pry__' # 上記のように変数が万が一nilだった場合にエラーになってしまうからだ。 以下のように記載すると良い! [6] pry(main)> c = [a, b].join => "b" [7] pry(main)> c = "#{a}#{b}" => "b"
sprintfよりはrjustを使ったほうが良い
# rubyのsprintfはrubyのバージョンや与える値、指定コードによって奇妙な動作を引き起こすことがあるので、rubyの標準関数であるrjustなどで同じことができるのであれば、そちらを利用したほうがバグなども発生しずらい為だ [1] pry(main)> sprintf('%03d', '1') => "001" [2] pry(main)> '1'.rjust(3, '0') => "001"
Rubyのbegin-end構文
# nilガードで変数に代入する際に複数行を記述する際に用いる [1] pry(main)> def test(test1) [2] pry(main)* @z ||= begin [3] pry(main)* if test1.nil? [4] pry(main)* 'nilです。' [5] pry(main)* else [6] pry(main)* 'nil以外です。' [7] pry(main)* end [8] pry(main)* end [9] pry(main)* end => :test [10] pry(main)> test(nil) => "nilです。" [11] pry(main)> @z => "nilです。"
参考記事
Rubyのbegin-end構文で変数を定義する - その辺にいるWebエンジニアの備忘録
What is use of ||= begin....end block in Ruby? - Stack Overflow
■
exit
とdetach
の違い
% docker ps ①動いているプロセスを確認 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES % docker ps -a ②止まっているプロセス含めて全て確認 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a390a72e29d7 ubuntu "bash" About an hour ago Exited (0) 2 minutes ago clever_neumann 4a36cf90b2e7 ubuntu "bash" About an hour ago Exited (130) About an hour ago angry_curran 32a488ae863e hello-world "/hello" About an hour ago Exited (0) About an hour ago clever_allen 693ca907f6fa order_form_app "entrypoint.sh bash …" 5 days ago Exited (0) 24 hours ago order_form_app_1 ae66d6f030c0 schickling/mailcatcher "sh -c 'mailcatcher …" 5 days ago Exited (0) 24 hours ago order_form_mailcatcher_1 43aa51f96062 redis:7.0 "docker-entrypoint.s…" 5 days ago Exited (0) 24 hours ago order_form_redis_1 1e5a9d4ac473 get_info_by_sql "docker-entrypoint.s…" 16 months ago Exited (255) 8 weeks ago 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp get_info_by_sql 2805557644bd ubuntu "ls" 16 months ago Exited (0) 16 months ago confident_dewdney 1fecffe609d7 docker/getting-started "/docker-entrypoint.…" 16 months ago Exited (255) 8 weeks ago 0.0.0.0:80->80/tcp, :::80->80/tcp modest_germain % docker restart a390a72e29d7 ③dockerのコンテナをupにしてプロセスを作る a390a72e29d7 ~ % docker ps ④上記でプロセスを起動したので、起動したプロセスが確認できる CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a390a72e29d7 ubuntu "bash" About an hour ago Up 5 seconds clever_neumann % docker exec -it a390a72e29d7 bash ⑤起動したコンテナの中に入れる root@a390a72e29d7:/# exit ⑥プロセスを終了してコンテナから抜ける exit % docker ps ⑥上記でプロセスを切ってコンテナから抜けたので、プロセスを確認すると無い CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES % docker restart a390a72e29d7 ⑦再度dockerのコンテナをupにしてプロセスを作る a390a72e29d7 % docker ps ⑧上記でプロセスを起動したので、起動したプロセスが確認できる CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a390a72e29d7 ubuntu "bash" About an hour ago Up 33 seconds clever_neumann % docker attach a390a72e29d7 ⑨上記で起動したプロセスに入る root@a390a72e29d7:/# read escape sequence ⑩ctrlキー + p + qでdetachする % docker ps 上記でdetachでコンテナから抜けたがプロセスが残ったままになっている CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a390a72e29d7 ubuntu "bash" About an hour ago Up About a minute clever_neumann
※
exit
だとプロセスを切って、コンテナから抜けるがdetach
だとプロセスを残したままコンテナから抜けることができる。
■
class SearchController < ApplicationController def search if postal_code = params[:postal_code] params = URI.encode_www_form({zipcode: postal_code}) uri = URI.parse("http://zipcloud.ibsnet.co.jp/api/search?#{params}") response = Net::HTTP.get_response(uri) result = JSON.parse(response.body) if result["results"] @zipcode = result["results"][0]["zipcode"] @address1 = result["results"][0]["address1"] @address2 = result["results"][0]["address2"] @address3 = result["results"][0]["address3"] end end end end
VS Codeの拡張機能
VS Codeの拡張機能で詰まったことがあったので、備忘録としてこちらにまとめます。
普段Railsで開発をしている時にhtmlファイル
だとEmmet機能が使えるが、erbファイル
だとEmmet機能が使えず不便なので調べたところ、Ruby on Rails Snippets
という拡張機能をインストールすればEmmet機能が使えることが分かった。(以下のアイコンになります。)
上記の拡張機能をインストールしたところ問題が発生した。
元々は、以下のようにapplication.html.erb
やGemfile
がカラーコードになっていたが、Ruby on Rails Snippets
をインストールしたところカラーコードでは無くなってしまった。
以下がRuby on Rails Snippets
インストール後
上記のようにEmmet機能は、有効になったがapplication.html.erb
やGemfile
がカラーコードでは無くなってしまった。
色々調べたところ、VSCode Ruby
という拡張機能をインストールすればカラーコードになるということが分かった。(以下のアイコンになります。)
上記をインストールしたところ以下のようにカラーコードになって、Emmet機能も使えるようになった。
参考記事
SendGridの導入
SendGridの導入
Railsの本番環境でメールを送信するようにする為には、一般的にSendGrid
orGmail
を使います。
今回は、SendGridでメールを送信できるようにする為の方法を備忘録としてこちらにまとめます。
まずSendGridに登録します。
下記URLより新規登録が必要になります。
Email Delivery, API, Marketing Service | SendGrid
※
・Herokuのアドオン経由でも登録できますが、SendGridのアカウントが凍結される可能性が高いのでSendGridの公式から直接登録する方が良いです!!
・SendGridの登録には、フィッシング詐欺の観点などから比較的に厳しい審査があります。
SendGridを使用してメールを使うWebサイトのドメインと自分の名前が紐付いて分かるような画像などが必要になります。
↓
SendGridのメール差出人情報を登録しておく必要があります。
まず、SendGridにログインしてAccount Details
をクリックしてタイムゾーンとメールアドレス(ユーザー名)が正しく設定されていることを確認する。
これらの情報は、宛先リストのアップロード完了通知メールや、スケジュール配信に使われます。
以下の手順で差出人情報を登録します。
①Marketing > Sendersをクリック
②Sender Management画面の右上のCreate New Sender
をクリック
③以下の情報を登録する
・From Name(From名):受信者に表示される送信者の名前
・From Email Address(Fromメールアドレス):メール送信者のメールアドレスとして表示される(自分のGmailなどを記載すると、そのGmailに認証のメールが届く)
・Reply-To Email Address(Reply-Toメールアドレス):受信者がメールの返信をする時に返信先のアドレスになる
・Company Address, City, State, Zip Code, Country(会社所在地):会社の所在地
・Nickname(一意な名前):差出人情報を識別するための名前(この名前が受信者に表示されることはない)
↓
Fromアドレス宛に認証メールが届くので、Verify Sender Identity
をクリック
これで差出人情報の登録は、終了
↓
SendGridのAPIキーを発行します。
手順は、以下のようになります。
①SendGridのマイページでSettings
→API Keys
をクリック
↓
②Create API Key
をクリック
↓
③API Key Name
に作成するAPIキーの名前を入力
して、API Key Permissions
はデフォルトのFull Access
のままにして、Create & View
をクリック
APIキーが発行されるので、コピーして安全な場所に保存する
Done
をクリック
これでAPIキーの発行は、終了
↓
メール送信サーバーの設定は、以下のようになります。
コードは、以下のようになります。
[app/mailers/application_mailer.rb] class ApplicationMailer < ActionMailer::Base default from: Rails.application.credentials.sendgrid.dig(:sender_address) # 送信するアドレスを記載(このように記載している理由は、後で説明します) layout 'mailer' end
念の為、開発環境でSendGridを利用する際の設定も以下に記載しておきます。
[config/environments/development.rb] config.action_mailer.perform_caching = false host = 'localhost:3000' config.action_mailer.default_url_options = { host: host, protocol: 'http' } config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => 'smtp.sendgrid.net', :port => 587, :domain => 'localhost', :user_name => 'apikey', # user_nameは、apikeyにする :password => Rails.application.credentials.sendgrid.dig(:sendgrid_api_key), # パスワードには、発行したAPIキーを入力(この記載は、後で説明します) :authentication => :plain, :enable_starttls_auto => true }
[config/environments/production.rb] config.action_mailer.default_url_options = { host: '自分のアプリのURL' } config.action_mailer.perform_caching = false config.action_mailer.delivery_method = :smtp config.action_mailer.perform_deliveries = true config.action_mailer.default :charset => "utf-8" config.action_mailer.smtp_settings = { address: 'smtp.sendgrid.net', port: 587, domain: 'heroku.com', user_name: 'apikey', # user_nameは、apikeyにする password: Rails.application.credentials.sendgrid.dig(:sendgrid_api_key), # パスワードには、発行したAPIキーを入力(この記載は、後で説明します) authentication: 'plain', enable_starttls_auto: true }
これで使用するメールサーバーの設定は、終了
↓
送信元のアドレスとメールサーバー設定のパスワードで、Rails.application.credentials
を用いているがこれは、config/credentials.yml.enc
に記載されている暗号化された値を復号して読み取る記述になる。
config/credentials.yml.enc
には、暗号化されたものが記載されている。
そもそもなぜ、config/credentials.yml.enc
のように暗号化されたものが必要になるかというと、APIキーやパスワード、メールアドレスなどの個人情報を設定ファイルなどに直接書き込むと、それをGitHubやサーバーにアップするのは、セキュリティ上危険なので、それらの値を暗号化したconfig/credentials.yml.enc
ファイルを設置しておき、それらの値を読み込みたい時は、config/credentials.yml.enc
からmaster.key
で復号して読み込むようにする。
つまり、master.key
をGitHubに公開したり、盗まれたりなどすると個人情報やAPIキーなどの重要情報がダダ漏れの状態になってしまう!!
その為、Railsでは通常.gitignore
にmaster.key
ファイルが記載されて、リモートにアップされないようになっている。
以下にconfig/credentials.yml.enc
に値を設定して、それらを暗号化しそれを読み出すまでの流れを以下に示します。
①以下でconfig/credentials.yml.enc
を編集
$ EDITOR="vi" bin/rails credentials:edit
vimでファイルが開き、以下のように記載して設定する。
aws: access_key_id: aaabbbcccddd secret_access_key: eeefffggghhh sendgrid: sendgrid_api_key: iiijjjkkklllmmm sender_address: nnnooopppqqq secret_key_base: rrrssstttuuu
保存して閉じるとconfig/credentials.yml.enc
が更新されて違う暗号となる。
上記のようにconfig/credentials.yml.enc
に設定した値がconfig/credentials.yml.enc
に暗号化されて記載されるが、これを復号して読み込む方法は、以下のようになる。
[1] pry(main)> Rails.application.credentials.aws[:access_key_id] => aaabbbcccddd [2] pry(main)> Rails.application.credentials.aws[:secret_access_key] => eeefffggghhh [3] pry(main)> Rails.application.credentials.sendgrid[:sendgrid_api_key] => iiijjjkkklllmmm [4] pry(main)> Rails.application.credentials.sendgrid[:sender_address] => nnnooopppqqq [4] pry(main)> Rails.application.credentials.secret_key_base => rrrssstttuuu
これでAPIキーやメールアドレスを暗号化しての記載は、終了
↓
herokuへデプロイする際は、.gitignore
にmaster.key
ファイルを記載している為、herokuへmaster.key
がアップされないので、Rails.application.credentials
でconfig/credentials.yml.enc
に記載されている暗号を復号できない。
herokuでは、以下のようにして復号化キーを環境変数RAILS_MASTER_KEYに登録する
heroku config:set RAILS_MASTER_KEY=********************************
※ポイント
・Credentialsは、最初にconfig/master.key
に復号化キーを探索しにいき、そこになければ次に環境変数のRAILS_MASTER_KEY
を探索しにいく。
そこにも復号化キーがなければ復号化に失敗し、nilが返却される。
・config/credentials.yml.enc
は、secret_key_base
によって暗号化される。
Credentialsにはsecret_key_base
が初めから登録されている。
これは、Cookieの暗号化に使用される文字列になります。
使わないからと言って削除しないように気を付けてください。
参考記事
[【Rails7】開発環境、本番環境でメール送信できるようにする(SendGrid, Gmail) | こばっちブログ
Rails5.2から追加された credentials.yml.enc のキホン - Qiita
Rails5.2でSendGridをつかってメールを送信する設定 | 煩悩八百万クリエイター戦記
本番環境とcredentials.yml.enc - Qiita
【Rails】Credentialsを使用した機密情報の保護 - AUTOVICE | 坂井光太郎のポートフォリオサイト
Heroku Addons で SendGrid を使ってる方が必要な年内対応 - ボクココ