ActionMailerのプレビュー
[ActionMailerのプレビュー]について
[ActionMailer]のプレビュー機能が便利だった為、こちらにまとめます
[ActionMailer]のプレビュー機能を使えば、実際にメールが送信されることはないので、何度もメールのレイアウトを確認することができる
プレビュー機能の手順を以下に示します
下記コマンドで、[ActionMailer]を生成する
$ rails generate mailer (メーラー名)
↓
上記で[ActionMailer]を生成した際に、[spec/mailers/previews/]のフォルダ以下にpreviewのファイルが生成されているので、こちらに記載する。
Railsガイドには、[test/mailers/previews/]フォルダ以下にpreviewファイルを配置するとなっており、文章のまま[test/mailers/previews/]を作ってしまったので注意が必要!!
以下に例を示します
[app/mailers/article_mailer.rb] class ArticleMailer < ApplicationMailer def report_summary mail(to: 'admin@example.com', subject: '公開済記事の集計結果') end end
[app/mailers/previews/article_mailer_preview.rb] class ArticleMailerPreview < ActionMailer::Preview def report_summary # メーラーと同じメソッド名で定義する ArticleMailer.report_summary #送信したいメーラーを呼び出す[(メーラー名).(メーラーのメソッド)] end end
↓
サーバーを起動して以下のURLにアクセスすると、メールのプレビューが確認できる
http://localhost:3000/rails/mailers/(メーラー名)/(メソッド名)
①
以下が例
http://localhost:3000/rails/mailers/user_mailer/welcome_email
↓
http://localhost:3000/rails/mailersで、使用できるメーラーが以下のように表示される
↓
メソッド名をクリックすると以下のようにメールがプレビューで表示される(このURLが①になる)
このメソッド名のリンク(report_summary)は、previewクラスに作成したreport_summaryメソッドに対応して表示される
※ポイント
[ActionMailer]のプレビュー機能では、メールが送信されているわけではないのでプレビューで表示されるからメールの送信機能も動いていると勘違いしないようにする
参考記事
オブジェクト指向とgetterとsetterとカプセル化
[オブジェクト指向とgetterとsetterとカプセル化]
[オブジェクト指向],[getter],[setter],[カプセル化]という言葉を見かけることが多いが、それらの意味をあまり理解していなかったのでこちらにまとめます
[オブジェクト指向]
○○指向というのは、〇〇を重視しているというような意味になる
例えば、恋人を選ぶ際にルックス指向や性格指向といった感じ
オブジェクト指向プログラミングというのは、オブジェクトをたくさん作ってアプリケーションを作るという事
Twitterで例えたら、ユーザーのアカウントというオブジェクトやTweetというオブジェクト、フォローというオブジェクトなどが集まってTwitterが出来上がるということ
[getter]と[setter]
[getter]というのは、クラスの外からオブジェクトの属性の値を参照できるようにするメソッドのこと
[setter]というのは、クラスの外からオブジェクトの属性の値を変えることができるようにするメソッドのこと
今回のように、オブジェクトの属性値を変更できるオブジェクトの事をミュータブルなオブジェクトという
以下に例を示します
class Food def name=(text) # setter: クラスの外からname属性に値をセットしたり変更したりできる @name = text end def name # getter: クラスの外からname属性の値を参照できる @name end end food = Food.new food.name = "寿司" p food.name => "寿司"
[カプセル化]
[カプセル化]というのは、クラスの外からオブジェクトの属性の値を参照出来ないようにしたり、値を更新できないようにすること
基本的には、オブジェクトの属性値は外部から値が更新されないようにカプセル化した方が良いことがほとんど
今回のように、オブジェクトの属性値が変更できないオブジェクトの事をイミュータブルなオブジェクトという
以下に例を示します
class Food private def name=(text) @name = text end def name @name end end food = Food.new food.name = "寿司" => エラーになる # クラスの中に[getter]と[setter]を記述しているが、privateにする事でクラスの外から[getter]と[setter]を呼び出せないようにして、クラスの外から値を参照したり、値を更新できないようにしている<br> p food.name => エラーになる
参考記事
複数ファイルのアップロード
複数ファイルのアップロード
複数ファイルをアップロードしたい時は、以下のように記述する(simple_formの場合)
[app/views ファイル] = f.input :main_images, as: :file, input_html: { multiple: true } # input_html: { multiple: true } というオプションを付ける
[app/controllers ファイル] def site_params params.require(:site).permit(:name, :subtitle, :description, :favicon, :og_image, main_images: []) end
上記のようにコントローラでストロングパラメータで複数ファイルをアップロードしたものを受け取る際は、配列になるのでmain_images: []のように記述する
参考記事
Swiper
Swiper
Swiperは、画像などを動的にスライドできるjQueryのプラグイン
導入手順は、以下のようになる
$ yarn add swiper
↓
[node_modules]にswiperがインストールされる
swiperの公式にあるように[swiper-bundle.css]と[swiper-bundle.js]を読み込むようにしなければいけない
今回は、swiperを使用するlayoutファイルに[application.js]と[application.css.scss]を使用していると仮定しています
[app/assets/javascripts/application.js] //= require swiper/swiper-bundle.js
[app/assets/stylesheets/application.css.scss] @import 'swiper/swiper-bundle';
上記のassetに記述したファイルのパスを以下に記述することで、絶対パスで記述しなくても読み込める
[config/initializers/assets.rb] Rails.application.config.assets.paths << Rails.root.join('node_modules')
[app/views/layouts/_header.html.slim] header .swiper-container .swiper-wrapper # スライドさせたい部分にクラスを付ける① - if current_site.main_images.present? - current_site.main_images.each do |main_image| = image_tag url_for(main_image), class: 'swiper-slide' # スライドさせる対象にswiper-slideというクラスを付ける - else = image_tag '/images/cover.jpg', class: 'swiper-slide' .container.blog-title h1 = link_to current_site.name, root_path p.lead = current_site.subtitle javascript: $(document).ready(function() { new Swiper('.swiper-container', { # ①のクラス名を利用 loop: true, autoplay: { delay: 3000, }, }) })
※ポイント
$(document).ready(function() { # 指定した処理 });
上記の記述は、DOMの読み込みが終わったらfunction()の中の処理を実行するという意味
JavaScriptは、HTMLが全て読み込まれてから出ないと正しく動作しない為、これを記述する
非同期通信(remote: true)で何かをクリックした時とかに[js.erb]ファイルをレスポンスする時は、ブラウザ上で画面が既に表示されているので、DOMの読み込みが終わっているが、今回のようにブラウザに画面が表示されるのと同時にJavaScriptを使う場合とかだと画面上のDOMが読み込まれているか分からないので、
[$(document).ready(function() {
});]
を記述する
参考記事
jQueryの基本 - $(document).ready - Qiita
JavaScriptの$(document).readyの使い方を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
swiperをyarnで導入して、画像をスライダー形式にする! - Qiita
【2021年版 RailsアプリにSwiper.jsでカルーセルを実装】 - Qiita
RailsでSwiperを導入する方法(Swiperは2020年7月にバージョンアップし、従来と設定方法が変わりました!) - Qiita
RailsでSwiperを導入する方法(Swiperは2020年7月にバージョンアップし、従来と設定方法が変わりました!) - Qiita
カスタムバリデーター
[カスタムバリデーター]とは?
モデルに記載するのとは別で、自分でバリデーションメソッドを作成することができる
[app/validators]を作成することで自動で読み込んでくれる
EachValidatorメソッド
[EachValidator]メソッドは、1つの属性に対しての検証を定義できる
[EachValidator]メソッドは、以下の3つを引数として受け取れる
・record: モデルのインスタンス
・attribute: 属性名
・value: 属性値
クラス名は、[検証名]Validatorの形式にする必要がある
以下に使用例を記述します
[app/models/site.rb] class Site < ApplicationRecord validates :og_image, attachment: { purge: true, content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } # [app/validators/attachment_validator.rb]に定義したattachment validates :favicon, attachment: { purge: true, content_type: %r{\Aimage/png\Z}, maximum: 524_288_000 } validates :main_images, attachment: { purge: true, content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } end
[app/validators/attachment_validator.rb] class AttachmentValidator < ActiveModel::EachValidator include ActiveSupport::NumberHelper def validate_each(record, attribute, value) return if value.blank? || !value.attached? has_error = false if options[:maximum] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_maximum(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_maximum(record, attribute, value) end end if options[:content_type] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_content_type(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_content_type(record, attribute, value) end end record.send(attribute).purge if options[:purge] && has_error end private def validate_maximum(record, attribute, value) if value.byte_size > options[:maximum] record.errors[attribute] << (options[:message] || "は#{number_to_human_size(options[:maximum])}以下にしてください") false else true end end def validate_content_type(record, attribute, value) if value.content_type.match?(options[:content_type]) true else record.errors[attribute] << (options[:message] || 'は対応できないファイル形式です') false end end end
上記でoptions[:maximum]は、バリデーションに定義したmaximumの値を参照できる(デバッグで確認した以下を参照)
[1] pry(#<AttachmentValidator>)> options[:maximum] => 524288000 [2] pry(#<AttachmentValidator>)> options[:content_type] => /\Aimage\/(png|jpeg)\Z/ [3] pry(#<AttachmentValidator>)> options[:purge] => true
参考記事
Visual Studio Codeの便利ツール
Visual Studio Codeの便利ツール
Visual Studio Codeの便利ツールがありましたので、こちらにまとめさせていただきます
[code]
下記のようにして[code]という拡張機能をインストールする
codeという拡張機能を入れると、下記のようにターミナルから[code ディレクトリ名]でVSコードで指定したディレクトリを開くことができる。
Node.jsとnodenvとyarn
Node.jsとnodenvとyarn
今までフロント部分について曖昧な事が多かったため、こちらにまとめさせていただきます。
Node.jsとは?
Node.jsは、JavaScriptがサーバー側で動くようにするものだが、今までJavaScriptのサーバー側バージョンの言語?と思っていたが、実は違った
Node.jsは、JavaScriptがサーバー側で動くようにするためのプラットフォームである。
そもそもRubyやJavaScriptなどのプログラミング言語が使えるようになるのは、プログラミング言語を理解できるプラットフォームがあるからである
Rubyの場合は、サーバー側にRuby言語が理解できるプラットフォームがあるからサーバー側でRubyが動く
JavaScriptの場合は、ブラウザ側にJavaScript言語が理解できるプラットフォームがあるからブラウザ側でugoku
Node.jsは、通常はブラウザ側にしかJavaScriptのプラットフォームが無いが、サーバー側でもJavaScriptを理解できるようにするためのプラットフォームである。
nodenvとは?
nodenvは、Node.jsのバージョン管理ツールである
yarnとは?
JavaScriptのライブラリを管理するパッケージマネージャ
[node_modules]フォルダとは?
yarnでインストールしたライブラリがインストールされる場所(Rubyだとvendorフォルダになる)
[package.json]ファイルとは?
yarnでインストールしたいライブラリ名とバージョンを記載したファイル(RubyだとGemfileになる)
[yarn.lock]ファイルとは?
yarnでインストールしたライブラリと、それの依存関係にあるライブラリと、それぞれのバージョンを記録しておくファイル(RubyだとGemfile.lockファイルになる)
Rubyに例えると以下のようなイメージ
Ruby | Node.js | |
バージョン管理ツール | rbenv | nodenv |
パッケージマネージャ | bundler | yarn |
インストールしたいライブラリを記載するファイル | Gemfile | package.json |
インストールしたライブラリが保存される場所 | vendor | node_modules |
インストールしたライブラリとそれの依存関係にあるライブラリと、それらのバージョンを保存しておくファイル | Gemfile.lock | yarn.lock |
Gemfile.lockやyarn.lockに記載されているライブラリをインストール+Gemfile.lock(yarn.lock)とGemfile(package.json)を比較してGemfile.lock(yarn.lock)に記載が無く、Gemfile(package.json)に記載があるライブラリがある場合は、そのライブラリに依存しているライブラリも含めてインストール | bundle install | yarn install |
Gemfile.lock(yarn.lock)に記載されているバージョンを参照せずにGemfile(package.json)に記載されている内容の範囲内で最新のライブラリをインストールし直す(ライブラリのバージョンが変わり今まで動いていたアプリケーションが動かなくなる可能性があるので、基本的にはやらない方が良い) | bundle update | yarn upgrade | Gemfileやpackage.jsonに記載せずに、指定したライブラリをインストールする | gem install (ライブラリ名) | yarn add (ライブラリ名) |
以下のファイルの位置でもRubyとの対応関係がイメージがつくと思います。
higmonta@higuchimiyukiyuunoMacBook-Pro 2563_higmonta_runteq_curriculum_advanced % which yarn /Users/higmonta/.nodenv/shims/yarn higmonta@higuchimiyukiyuunoMacBook-Pro 2563_higmonta_runteq_curriculum_advanced % which bundler /Users/higmonta/.rbenv/shims/bundler