はとのーと

エジソンノート(アイデア、思い付き、メモ)として使っています。誰かの役に立つかもしれないので公開しています。

Railsについてのメモ

(2023-11-02更新)

Ruby on Railsについての自分用メモです。

ルーティング

config/routes.rb に記入する。

リソース全体を登録するには resoures :books のように書く。

限定、除外するにはそれぞれ only, except をつける。

resources :books, only: [:index, :show]
resources :authors, except: [:destroy, :update]

ルーティングの確認方法:

  • Rails コンソールから rails routes を実行
  • http://localhost:3000/rails/info/routes にアクセス

ActiveRecord で最終 n 件を取得する

Books.all.order(name: 'DESC').limit(5)

結果は降順で取得される (order は1度しか指定できないため)。

昇順で取得したい時はサブクエリを使って次のようにする。

Books.all.order(:name).where(id: Books.all.order(name: 'DESC').limit(5).select(:id))

その他

  • bundlerでgroup :production以外をインストールする: bundle install --without production
  • サンドボックスでコンソールを開く: rails console --sandbox
  • 特定の環境用にコンソールを開く: rails console --environment {環境}
  • generate: rails generate controller StaticPages home help, rails generate model User name:string email:string
    • コントローラやリソースは複数形、モデルは単数形で指定する
    • rails generate modelするとマイグレーションファイルが作成されるので、中身を確認してから rails db:migrate を実行してデータベースに反映させる
  • generateを取り消す: rails destroy model User (Qiita)
  • モデルでハッシュ化したパスワードを使う: モデル内にhas_secure_passwordを入れる。テーブルのpassword_digestに格納される
  • assertion:
    • レスポンスコード: assert_response :success (doc)
    • テンプレートの使用: assert_template "users/new"
    • 要素が存在する: assert_select "title", "Sign up", assert_select "div#message" (Qiita)
    • 要素が存在しない: assert_select "title", false, "Sign up", assert_select "div#message", false (APIdock)
    • 状態に変更がない: assert_no_difference "User.count" {ブロック}
    • 状態に変更がある: assert_difference "User.count", 1つ増える→assert_difference "User.count", 1
  • flashflash.now:
    • フラッシュメッセージを表示する。flash[:notice]="message", flash.now[:alert]="message"のように使う (Qiita)
    • flash:
      • 主にredirect_toメソッドとセットで使用する
      • 次のアクションまでメッセージが残る
      • 注意: renderで使うとrenderの次のアクションのページにもメッセージが残る
    • flash.now:
      • 主にrenderとセットで使用する
      • 次のアクションに移行した時点でメッセージは消える
      • 注意: redirect_toとともに使うとメッセージが表示されない (redirect_toが次のアクションとなるため)
  • debugger
    • debuggerを記入するとデバッグセッションが開始される (Zenn)
    • next(またはn)でシングルステップ実行
    • continue(またはc)で実行を再開し、quit(またはq)で実行を中断する。
  • ActiveRecord
    • update_attribute: 単一アトリビュートを更新する。バリデーションは実行されない
    • update_attributes: 複数アトリビュートを更新できるがバリデーションが実行される
  • db:migrate
    • 基本操作はrails generate migration 〜(マイグレーション作成)→rails db:migrate(適用)
    • 最後に適用したものを戻す: rails db:rollback
    • 現在の適用状況を見る: rails db:migrate:status
    • 最初から適用し直す: rails db:migrate:reset
    • マイグレーションファイルの作成:
      • モデル作成時: rails generate model User name:string email:string
      • フィールドの追加: rails generate migration add_password_digest_to_users password_digest:string
      • 固定小数点フィールドはt.decimal :fieldname, precision: 11, scale: 3のように作成する (この場合全11桁のうち小数点以下3桁)
  • db:seed
    • db/seeds.rbファイルで初期値を設定する
    • 初期値の投入はrails db:seed
    • 複数回実行するとデータが複数回追加されたりIDを指定している場合には重複の問題があるためrails db:migrate:resetでデータベースを作り直してから実行する方がよい
  • Railsバージョンアップ: Gemfileのバージョンを変更し、bundle update railsを実行 (Qiita)

Rubyについてのメモ

調べたことなど。

メソッドが定義されているクラスを調べる

参考: 【Ruby】メソッドが定義されているクラスを調べる

object.method(:method_name).owner で調べる。

>> a = (1..3).to_a
=> [1, 2, 3]

>> a.length
=> 3

>> a.method(:length).owner
=> Array

>> b= "abc"
=> "abc"

>> b.length
=> 3

>> b.method(:length).owner
=> String

Gemのインストール先を調べる

$ gem environment gemdir
/usr/local/bundle

$ gem which sqlite3
/usr/local/bundle/gems/sqlite3-1.4.2/lib/sqlite3.rb

Visual Studio Codeについてのメモ

VSCodeについての自分用メモ。

目次:

編集画面Tips

  • Ctrl + Shift + Pでコマンドパレットが表示される
  • 文字列をHTMLのタグで囲みたい時は文字列を選択してからコマンドパレットからEmmet: Wrap with Abbrebiationを実行する

リモートDockerコンテナで開発する

SSHで接続した先のリモートホスト上で動くDockerコンテナ内で開発する方法。 開発環境はDockerコンテナ内に構築する。 ローカルマシンにはDockerも開発言語もインストールしなくてよい。

VSCode拡張機能の準備
  1. クライアント側から公開鍵でパスワードなしで ssh ユーザ名@ホスト名 で接続できるようにしておく
  2. ローカルにVS Codeをインストールする
  3. 拡張機能 Visual Studio Code Remote Development Extension Pack (Remote Development)をインストールする
Dockerfileを準備する

ソースコードリモートホスト上に置く。 正常にビルドできるDockerfileを用意する。

次のように開発用ユーザーを追加する記述も入れておく。

RUN addgroup -g 1000 devuser && \
    adduser -u 1000 --home /tmp devuser -G devuser -D
devcontainer.jsonを準備する

Dockerを実行するディレクトリに.devcontainerディレクトリを作成し、その中にdevcontainer.jsonを作成する。 以下のような内容で事前に準備してもよいが、なければ初回接続時に一般的な内容のものが作成される。

.devcontainer/devcontainer.json:

{
    "name": "testdev",
    "build": {
        "dockerfile": "../Dockerfile"
    },
    "forwardPorts": [3000],
    "remoteUser": "devuser"
}

"remoteUser"にはDockerfileで作成したユーザーを指定する。

初回接続
  1. 左下の><をクリックし、[ Connect Current Window to Host... ] を選択する
  2. ホストを選択するか、+ Add New SSH Host... をクリック → 上記 ユーザ名@ホスト名 を入力 → .ssh/hosts を選択 → Open Remote を選択する
  3. ソースコードのあるディレクトリを開く
  4. コマンドパレットから [ Reopen in Container ] を選択する

もしdevcontainer.jsonファイルがない場合には、 From Dockerfile を選択してDockerfileを指定するとdevcontainer.jsonファイルが作成される。

初回はコンテナをビルドするため時間がかかる。

ビルドに失敗して、その後に修正しても反映されない場合には、リモートホスト上でdocker ps --allをしてエラーを起こしたコンテナが残っているか確認する。 もしコンテナが残っていたらdocker rm コンテナIDで削除するとビルドできるようになる場合がある。

2回目からの接続

2回目からは次のどちらかで接続できる。

  • [ Connect Current Window to Host... ] で接続し [ Reopen in Container ] を実行する
  • VSCode の「最近使用した項目」から [ Dev Container: 〜 ] と書かれている項目を選択する

なお、Dockerfile内ではUID、GIDともに1000で作成したが、Remote Developmentを使うと実行時に利用者のUID、GIDに変更してくれる。

参照: Docker や VSCode + Remote-Container のパーミッション問題に立ち向かう