【Rails】enumについて
はじめに
enumについて記述していきます。
enumとは?
enumとは、1つのカラムに指定した複数個の定数を保存できる様にする為のモノです。
例 user.rb
class User < ApplicationRecord enum role: { general: 0, admin: 1 } end
このenumを使うと指定した複数個の定数以外の値は保存できない様にしたり、カラムに指定した定数が入っているレコードを取り出すのが容易になったりと多くのエンジニアが頻繁に使用する大変便利なメソッドです。
enumの定義方法
マイグレーションファイル
class AddRoleToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :role, :integer, null: false, default: 0 end end
これでuserにroleという役割カラムを作成しました。integer型なので整数しか入りません。 enumはこの数値に定数を与えることができます。
それが先ほど例で出したものです。
user.rb
class User < ApplicationRecord enum role: { general: 0, admin: 1 } end
つまり、新規作成したuserは基本0の値が入るのでroleカラムにgeneralが入ります。
【Rails】AdminLTEについて
はじめに
管理画面を作るのが大変。そこで、管理画面作成に特化したCSSフレームワークAdminLTEについて記していきます。
インストール
$ yarn add admin-lte@^3.0
このように様々なファイルが取り込まれます。 yarnでインストールしたので、ルートディレクトリ直下の、node_modules/以下を確認しましょう。
いろいろ展開されますが、adminLTEの本体はdist以下に格納されています。 あとは、依存関係のあるbootstrap, jquery(plugins/jQuery/)などなど。
これをRailsで読み込んでいきます。
まず、app/assets/stylesheets/admin.scssとapp/assets/javascripts/admin.jsを作成しましょう。
ここには、何を読み込むかを記載します。 たとえば、
app/assets/stylesheets/admin.scss
@import 'admin-lte/dist/css/adminlte.min.css';
app/assets/javascripts/admin.js
//= require admin-lte/dist/js/adminlte.min
このような、形で読み込みます。これは、node_modulesから取り込んでいます。 では、どうやってadmin-lte/dist/js/adminlte.minを探しているのか? node_modules/admin-lte/dist/js/adminlte.minではないのか?
それは、 config/initializers/assets.rbにパスが書いてあるからです。
assets.rb
Rails.application.config.assets.version = '1.0' # パスの記述 Rails.application.config.assets.paths << Rails.root.join('node_modules') # 他のマニフェストや、個別のスタイルシート/JavaScriptファイルをインクルードしたい場合は、config/initializers/assets.rbのprecompileという配列を使用します。 Rails.application.config.assets.precompile += %w[admin.js admin.scss]
これで準備完了です。
layoutsの指定
あとは、viewにこのadmin.scssとadmin.jsを参照するlayoutを指定しましょう。
admin/layouts/admin.html.erb
<!DOCTYPE html> <html> <head> <title><%= page_title(yield(:title)) %></title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'admin', media: 'all' %> #ここをadminに変更 <%= javascript_include_tag 'admin' %>#ここをadminに変更 </head> <body> <%= yield %> </body> </html>
###あとは使用したいコントローラーにlayoutメソッドを使用し、使用したいlayoutを指定します。
controller
class Admin::UserSessionsController < Admin::BaseController layout 'admin_login' #こんな感じ def new; end def create @user = login(params[:email], params[:password]) if @user&.admin? redirect_to admin_root_path, success: 'ログインしました' elsif @user redirect_to root_path, danger: '権限がありません' else flash[:danger] = 'ログインに失敗しました' render :new end end def destroy logout redirect_to admin_login_path, success: 'ログアウトしました' end end
【JavaScript】yarnについて
はじめに
yarnとは何かについて分からなかったので、整理しました。
yarnとは?
Node.jsで動作するパッケージマネージャーの一つです。
フロントエンド関連のパッケージ管理ツールは様々混在していますが、大枠 Bower → npm → yarn と言った流れを経てきています。
Node.jsとは?
Node.jsというのは、JavaScriptでサーバーサイドの処理を可能にさせるプログラムです。 「Node.js = サーバサイドJavaScript」だと認識しておけばいいとどこかに書いてありました。(正確ではないらしい)
パッケージマネージャーとは?
「パッケージマネージャとは、コンピュータに何のソフトウェアがインストールされたかを記録し、新しいソフトウェアのインストール・新しいバージョンへのソフトウェアの更新・以前インストールしたソフトウェアの削除を容易に行えるようにするプログラム」
要するに
yarnとnpmはJavaScriptでサーバーサイドの処理を行うために使うプログラム(Node.js)上で使うパッケージマネージャーということです。
フレームワークなどを使うにはインストールが簡単でじゃなきゃ?
何個ものプログラムでできているフレームワークをインストールするとします。それを動かすために必要なプログラムを全て手作業でサーバーの適切な場所にコピーし、特定の設定ファイルを書き換え、正常にインストールできたかを確認し、バージョン管理をするのはとても大変なことです。
パッケージマネージャ全て管理してくれる!!
簡単なコマンドの入力でインストールを完了することができる。
yarnについて
- JavaScriptのパッケージマネージャ
- 2016年にFaceBookが公開した
- npmと互換性がある = 同じpackage.jsonが使える
yarnのメリット
- npmよりインストールが速い
- 約半分になる場合もあるそう
- npmより厳密にモジュールのバージョンを固定できる
- yarn.lockファイルで、各パッケージのインストールバージョンを固定できる。
- npmと一緒に使える
- npmと同じのpackage.jsonが使えるため、同一プロジェクトでnpm or yarnで固定しなくて良い。
yarnのインストール
$ sudo npm install -g yarn
package.jsonの生成
パッケージを一括管理できるpackage.json。 プロジェクトにまだpackage.jsonがない場合、以下のコマンドで生成できる。
$ yarn init
yarnでパッケージをインストール
package.jsonに記載されたモジュールをインストールする。
$ yarn
パッケージの追加
以下のコマンドでパッケージのインストールとpackage.jsonへの追加ができる。
$ yarn add [パッケージ名]
npmではnpm install --saveだった。
パッケージのアンインストール
以下のコマンドでパッケージのインストールとpackage.jsonへの追加ができる。
$ yarn remove [パッケージ名]
npmではnpm uninstall
参考資料
【Rails】gem configについて
はじめに
アプリを開発していく中で本番環境と開発環境で値を変えたいといったケースが出てくると思います。たとえばホストの情報を管理したい時などに使えます。メールを送る下準備としてホスト情報を設定しておく必要があるのですが、ホスト情報って開発環境、ステージング環境、本番環境で異なりますよね? 例えばこのように。
これを素直に実装しようとするとこのようになるはずです。 gem configを利用することで、Ruby on Railsで便利に定数を管理することができます。
設定
Gemfile
gem 'config'
$ bundle install
初期設定
以下のコマンドを実行して、configの初期設定をおこなっていきます。
$ bundle exec rails g config:install Running via Spring preloader in process 30847 create config/initializers/config.rb create config/settings.yml create config/settings.local.yml create config/settings create config/settings/development.yml create config/settings/production.yml create config/settings/test.yml append .gitignore
「config/」以下にいろいろとconfig関連のファイルが生成されました。
設定方法
web: host: 'localhost:3000'
例 config/settings/development.yml
Settings.service.name Settings.service[:name] Settings[:service][:name]
【Rails】gem letter_opener_webについて
はじめに
Ruby on Railsで開発中に送ったメールを確認する Gem letter_opener_webの使用方法の紹介です。 このように、開発環境で簡単に送られたメールを確認することができます。
設定方法
Gemfile
group :development do gem 'letter_opener_web' end
次に、 development.rb
# Rails.application.configure do #配信方法 config.action_mailer.delivery_method = :letter_opener_web # default_url_optionsの設定は、電子メールテンプレートのリンクURLを構築するのに便利です。 config.action_mailer.default_url_options = { host: 'localhost:3000' } end
routes.rb
Rails.application.routes.draw do mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development? end
使用方法
ブラウザで
http://localhost:3000/letter_opener
と入力するだけです。
【Rails】sorcery(Reset password)
はじめに
sorceryとは、Railsに認証機能の実装を行うためのライブラリです。 同じように認証機能を提供してくれているものとしてdeviseなどが挙げられますが、sorceryの方がよりシンプルで、カスタマイズ性に富んでいるという特徴を持ちます。今回はsorceryのReset Passwordモジュールの実装方法を記していきます。
実装方法
モジュールのインストール
$ rails g sorcery:install reset_password --only-submodules Running via Spring preloader in process 30110 gsub config/initializers/sorcery.rb insert app/models/user.rb create db/migrate/20200419075054_sorcery_reset_password.rb
これで、password_resetサブモジュールを使用するための記述がconfig/initializers/sorcery.rbに、自動で行われました。また、マイグレーションファイルなども作成されます。
マイグレーションファイル
class SorceryResetPassword < ActiveRecord::Migration[5.2] def change add_column :users, :reset_password_token, :string, default: nil add_column :users, :reset_password_token_expires_at, :datetime, default: nil add_column :users, :reset_password_email_sent_at, :datetime, default: nil add_column :users, :access_count_to_reset_password_page, :integer, default: 0 add_index :users, :reset_password_token end end
この、マイグレーションファイルをDBに反映させます。
$ rails db:migrate
パスワードリセット用のMailerを作成
まず、Mailerを作成します。
$ rails g mailer UserMailer reset_password_email Running via Spring preloader in process 88211 create app/mailers/user_mailer.rb invoke erb create app/views/user_mailer create app/views/user_mailer/reset_password_email.text.erb create app/views/user_mailer/reset_password_email.html.erb
次に、config/initializers/sorcery.rbの中で、sorceryのパスワードリセットに使用するActionMailerをUserMailerで指定します。
config/initializers/sorcery.rb
Rails.application.config.sorcery.submodules = [:reset_password] Rails.application.config.sorcery.configure do |config| config.user_config do |user| # パスワードリセット用のMailerにUserMailerを指定する user.reset_password_mailer = UserMailer end end
それでは、パスワードリセット用のメソッドを記述します。
class UserMailer < ApplicationMailer def reset_password_email(user) @user = User.find(user.id) @url = edit_password_reset_url(@user.reset_password_token) mail(to: user.email, subject: 'パスワードリセット') end end # reset_password_emailメソッドなので、reset_password_email.〇〇のビューがメールのフォーマットになる # メイラーのメソッド内で定義されたインスタンス変数はメイラーのビューで使える。
最後に、メイラービューの設定をします。
app/views/user_mailer/reset_password_email.html.erb
<h1><%= @user.decorate.full_name %>様</h1> <p>=====================================</p> <p>パスワード再発行のご依頼を受け付けました。</p><br> <p>こちらのリンクからパスワードの再発行を行ってください。</p> <p><a href="<%= @url %>"><%= @url %></a></p>
app/views/user_mailer/reset_password_email.text.erb
<%= @user.decorate.full_name %>様 =========================================== パスワード再発行のご依頼を受け付けました。 こちらのリンクからパスワードの再発行を行ってください。 <%= @url %>
リセットをするためのフォームからコントローラまで
routes.rb
resources :password_resets, only: %i[new create edit update]
まずは、パスワードリセットのトークンを発行しメールを送るためのフォーム。
passowrd_reserts/new.html.erb
<% content_for(:title, t('.title')) %> <div class="container"> <div class="row"> <div class=" col-md-10 offset-md-1 col-lg-8 offset-lg-2"> <h1><%= t('.title') %></h1> <%= form_with url: password_resets_path, method: :post, local: true do |f| %> <div class="form-group"> <%= f.label :email, User.human_attribute_name(:email) %> <%= f.email_field :email, class: 'form-control' %> </div> <div class="actions"> <%= f.submit t('default.sent'), class: 'btn btn-primary' %> </div> <% end %> </div> </div> </div>
email情報からパスワードをリセットしたい、userを抜き出す。
app/controllers/password_resets_controller.rb
class PasswordResetsController < ApplicationController skip_before_action :require_login def new; end def create @user = User.find_by_email(params[:email]) # ここで先ほど定義したメソッドのapp/mailers/user_mailer.rbへ @user&.deliver_reset_password_instructions! redirect_to login_path, success: 'パスワードリセット手順を送信しました' end def edit @token = params[:id] @user = User.load_from_reset_password_token(params[:id]) not_authenticated if @user.blank? end def update @token = params[:id] @user = User.load_from_reset_password_token(params[:id]) return not_authenticated if @user.blank? @user.password_confirmation = params[:user][:password_confirmation] if @user.change_password(params[:user][:password]) redirect_to login_path, success: 'パスワードを変更しました' else flash.now[:danger] = 'パスワードを変更できませんでした' render action: 'edit' end end end
createメソッドが動き、さきほどの設定したメールテンプレートが送信されます。そのトークンが含まれたURLからeditアクションを起動しapp/views/password_resets/edit.html.erbへ遷移されます。
app/views/password_resets/edit.html.erb
<% content_for(:title, t('.title')) %> <div class="container"> <div class="row"> <div class=" col-md-10 offset-md-1 col-lg-8 offset-lg-2"> <h1><%= t('.title') %></h1> <%= form_for @user, :url => password_reset_path(@token), :html => {:method => :put} do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="form-group"> <%= f.label :email %><br /> <%= @user.email %> </div> <div class="form-group"> <%= f.label :password %><br /> <%= f.password_field :password, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation, class: 'form-control' %> </div> <div class="actions"> <%= f.submit class: 'btn btn-primary' %> </div> <% end %> </div> </div> </div>
このフォームでボタンを押すと、updateアクションが起動し、パスワードリセット完了です。
参考資料
【Rails】日時フォーマット(lメソッド)
はじめに
Viewにcreated_atのような日付を出力すると、
Tue, 30 Jul 2020 00:12:12 +0000
のような日本人には見慣れない表示がされます。この記事ではこれを日本人が見やすい表示に変更する流れを紹介します。
タイムゾーンを日本時間にする
まず、タイムゾーンを日本時間にしましょう。
config/application.rb
module Normal class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.2 # アプリケーション側のタイムゾーン config.time_zone = 'Tokyo' # DB側から受け取った時刻をどのタイムゾーンとして解釈するか config.active_record.default_timezone = :local end end
これで画面に表示される日時が日本時間になります。
Tue, 30 Jul 2020 09:12:12 +0900
日本人が読みやすいフォーマットにする
lメソッドをしようするのですが、そのまえに準備をします。 先ほどのapplication.rbに以下を追記します。
# デフォルトの言語を日本語に変更 # デフォルトは:enになっている config.i18n.default_locale = :ja # localeファイルの読み込み設定 config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
続いて、 config/locales/ja.ymlというファイルを作成し、以下の記述をします。
ja: time: formats: default: "%Y/%m/%d %H:%M:%S"
これで準備OKです。 View側で
<%= l user.created_at %>
と記述してみましょう。
2020/11/30 09:12:12
とわかりやすい表示になっているはずです。
応用編
他にも、ja.ymlの指定を増やせばいろいろな形のフォーマットを実現できます。
ja.yml
ja: time: formats: default: "%Y/%m/%d %H:%M:%S" short: "%m/%d %H:%M"
View側
<%= l user.created_at, format: :short %>
11/30 09:12
このように、フォーマットを作ることができます。