Amazon LightsailのWordPressのphpMyAdminに接続する

LightsailのwordpressにはphpMyAdminがインストールされていますが、デフォルトではローカルホスト以外からの接続は拒否されてしまいます。SSHポートフォワーディングを使うことで安全にphpMyAdminに接続することができます。

ssh [HOST] -L 8080:localhost:80 -N

あとはブラウザで http://localhost:8080/phpmyadmin でphpMyAdminにアクセスできます。

ログインアカウント名は root、パスワードはホームディレクトリの bitnami_application_password です。

Heroku Postgres のデータベースをローカルの開発環境にリストアする

Herokuの本番環境のデータベースをローカル環境にコピーして利用したい場合の手順。

データベースのバックアップを作成

heroku pg:backups capture --app app_name

コマンドを実行するとバックアップが実行される。しばらくしてバックアップが終了すると以下のように表示されるので、バックアップ名(b001の部分)を控えておく。

Backing up DATABASE to b001... done

バックアップをローカルにダウンロード

heroku pg:backups:download b001 --app app_name

先ほど控えておいたバックアップ名を指定してダウンロードする。カレントディレクトリに latest.dump という名前でダンプファイルが作成される。

データベースのリストア

pg_restore --verbose --clean --no-acl --no-owner -h localhost -U user_name -d database_name latest.dump

S3の特定のプレフィックスのオブジェクトをいっぺんに消す

アクセスログのプレフィックスを logs/ と間違えて logs としてしまい、ルートディレクトリに logs2020-03-19-01-40-54-C990FDCF5A1EE0AA みたいなファイルがたくさんできてしまったので削除したかった。

aws --profile profile-name s3 rm s3://bucket-name/ --exclude '*' --include 'logs*'

--dryrun オプションをつけると dry run できる。

aws --profile profile-name s3 rm s3://bucket-name/ --exclude '*' --include 'logs*' --dryrun

RailsでNOT NULL制約をマイグレーションでつける

Railsで、NOT NULL制約がついてないカラムに後からマイグレーションでNOT NULL制約をつける時のやり方。

migrateファイルで、change_column_nullを使う。DEFAULTも設定する場合はさらにchange_column_defaultも行う必要がある。

class ExampleMigration < ActiveRecord::Migration[6.0]
  def change
    change_column_null :table, :column, false, true
    change_column_default :table, :column, from: nil, to: true
  end
end

change_column を使うと PG::NotNullViolation: ERROR: column "column" contains null values の様に、すでにレコードが作成されていた場合はエラーになってしまう。change_column_nullを使うとNULLのカラムをデフォルト値(4パラ目)でUPDATEしてからNOT NULL制約をつけてくれる。

Railsで特定のコントローラーでセッションを使わないようにする

Railsはコントローラーで session に書き込みを行うとセッションIDがアサインされ、Set-CookieでCookieにセッションIDが設定される。

デフォルトでは全てのリクエストでCSRFトークンをセッションに格納しているため、何も設定していないとランディングページなどのセッションをあまり必要としない静的ページへのアクセスでセッションストアの容量が圧迫されたりしてしまう。

コントローラーで protect_against_forgery? をオーバーライドして false を返すようにすると、session に書き込みが行われないため、新規にセッションIDがアサインされなくなる。

class StaticPagesController < ApplicationController
  skip_before_action :authenticate_user!

  parivate

  def protect_against_forgery?
    false
  end
end

ただし当然ながらCSRFトークンが作成されなくなるため、使いどころは注意されたし。

外部サービスで使用しているPostgresqlのデータベースをHeroku Postgresにリストアする

基本的にはHerokuのドキュメントに全て書いてある。
https://devcenter.heroku.com/articles/heroku-postgres-backups

今回はAWS EC2のRailsアプリケーションをHerokuに移行した時のデータベースのコピーしたので、手順をメモしておく。

AWSサービス側での操作

  1. メンテナンス画面にした後、冗長化してあるWEBサーバーを止めて1台のシングル構成に。
  2. パブリックディレクトリ(Herokuがアクセスできる場所)にPostgresqlのダンプファイルを作成する。念のため、ファイル名は乱数にでもしておく。
PGPASSWORD=$PG_PASSWORD pg_dump -Fc --no-acl --no-owner -U $PG_USER -h $PG_HOST -p $PG_PORT $PG_DATABASE -f /var/www/app/current/public/xxxxxxxxxx.dump

Heroku側での操作

heroku pg:backups:restore 'https://www.app.com/xxxxxxxxxx.dump' DATABASE_URL --app=app-name --confirm=app-name

これでHerokuにDBがコピーされるので、ドメインをHerokuに向けてメンテナンスを解除する。

注意

heroku pg:backups:restore を実行すると、URLにアクセスできなかったなどの理由でリストアに失敗した場合でもHeroku Postgres のデータベースは削除されてしまう。

Railsコンソールで手っ取り早くバリデーションの動作確認をするワンライナー

->(c, k, v) { c.new(k => v).tap(&:valid?).errors[k] }.call(User, :email, "text@example.com")

ポイント

  • tap内 で valid? を実行することでメソッドチェーンで errors が呼び出せる。
  • ラムダ式を使って変数がコードの後ろに来るようにしてあるので、コンソール内で値を変えながら何度も動かしてみるのが楽。

請求書より入金額が少ない時の帳簿の付け方

個人事業主で freee で帳簿をつけていて、相手型のミスで請求書より少ない金額が入金され、翌月に前月の不足額を加算した金額で入金された時の帳簿の付け方。

  • 売上高は請求書通りにする
  • 前月の不足額を事業主貸にする
  • 翌月の超過額を仮受金にする

Rubyの論理和

  • Rubyの || 演算子は、「左辺を評価し、結果が真であった場合にはその値を返します。 左辺の評価結果が偽であった場合には右辺を評価しその評価結果を返します。」https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html#or
  • なので、結果はBoolean(true, false)ではなく、「右辺もしくは左辺の評価結果」になる。
  • 「右辺か左辺の少なくとも1つが真の場合に真」みたいな解説をちらほら見かけるが、正確ではない。

Ransackのsort_linkのURLクエリからパラメーターを除外する

Ruby on Railsで、ransackのsort_linkヘルパーを使うと、?q%5Bs%5D=name+asc のようなURLのアンカーを作成してくれる。

この時、同時にkaminariでページネーションをしていると、sort_linkはparamsを自動的にマージするので、?page=2&q%5Bs%5D=name+asc のようなURLになる。

sort_link :id, page: nil のようにpageパラメータをnilで上書きしてあげると、作成されたURLのクエリにpageは設定されなくなる。

なお、sort_link :id, params: { page: nil } では pageは上書きされない。sort_link :id, params: { page: 1 } と書くとURLのクエリにpageが2つ設定される。

ransackのソースコードを見ると、paramsとsort_linkに指定したオプションをマージして直接 url_for に設定している。

https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/helpers/form_helper.rb#L131

def url_options
  @params.merge(
    @options.merge(
      @search.context.search_key => search_and_sort_params))
end

https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/helpers/form_helper.rb#L92

send(routing_proxy).url_for(options_for_url)