Rails関連のことを調べてみた

Rails関連のことを調べてみた

Rails アプリに E2E テストを導入する(技術選定編)

E2E テストを導入するにあたり、技術選定で調べたことをまとめてみました

## とりうる選択肢とそれぞれの特徴

1. System Spec 経由で Capybara を使い Selenium をドライバーとして動かす
– System Spec 自体が RSpec に組み込まれており、かつ Selenium が Capybara のメジャーなドライバーなので rails でE2Eテストをする場合の標準的なテストスタックと言える。rspec と統一された設定、環境で E2E テストが行える
1. System Spec 経由で Capybara を使い Playwright をドライバーとして動かす
– Selenium をドライバーとして使った場合、テストが正常に実行されない場合があるので、その点を解消したい場合はこちら。Rails 7.1 であれば Playwright 用の設定が組み込まれているので gem をインストールすればそのまま使えるが、Rails 7.0 以前でも別途設定を行えば使える
1. Capybara を直接動かす
– 詳細な設定や Sin

元記事を表示

Railsガイド +αメモず【MVC周り】

# はじめに
素人の戯言なんですが、
「フィルタ」と聞くと`Array.filter`しか思いつかないんですよね。
(つまり、集合からの抽出)

Rails MVCのコントローラの文脈で「フィルタ」が出てきたので
「それはなんぞや」ということで調べました。

ついでに、MVCモデル周りでわからなかったことをまとめてます。
いつも通り書き捨ての文です。よろしくお願いします。

# メモず
## コントローラ
### フィルタって?
コントローラのアクション前後に特定のメソッドを実行する機能のようです。
viewにおける`application.html.erb`ですね。
**この「特定のメソッド・共通の処理」を「フィルタメソッド」と呼ぶらしいです。**
(Rails独特の言い回し)

具体的には、以下の3つが当てはまります。
> 1. **before_action(または before_filter)**:
>
> – アクションが実行される前に呼び出されます。
> – 認証チェック、パラメータの検証、セッションの確認などに使用されます。
> 2. **aft

元記事を表示

each などのarrayメソッド時の、break, return, nextの挙動

## break
ループを抜ける

“`
users.each | user | do
puts user
break if user == ‘hoge太郎’
end
 →userが「hoge太郎」の時、ループを終了しeach処理を抜ける
“`

# return
メソッドを抜ける

“`
class hogehoge
def puts_name(users)
users.each | user | do
puts user
return if user == ‘hoge太郎’
end
end
 →userが「hoge太郎」の時、hogehogeメソッドを抜ける
“`

# next
ループの次の要素に行く

“`
users.each | user | do
puts user
next if user == ‘hoge太郎’
puts ‘hoge太郎のときは出力されないよ’
end
 →userが「hoge太郎」の時、次の要素に即座に行く、後続の処理(ここで言う、puts)は実行されない
“`

元記事を表示

ActiveRecord scopeについて

## scope とは
クエリを定義できるもの
よく使うものであったり、変数的に命名したいものを定義できる
引数を渡すこともできる

## 例
“`
class Post < ApplicationRecord scope :published, -> { where(published: true) }
scope :recent, ->(days_ago = 7) { where(“created_at >= ?”, Time.now – days_ago.days) }
end
“`

## クラスメソッドとの使い分け
条件分岐など、ロジックが複雑になりそうなものに関しては、クラスメソッドを定義する

“`
class Post < ApplicationRecord def self.recent(days_ago = 7) where("created_at >= ?”, Time.now – days_ago.days)
end
end
“`

元記事を表示

preload, eager_load, include の違い

## preload, eager_load, includeとは
N+1を解消する、ActiveRecordのメソッド

## 前提
下記、違いについての説明は、この2モデルが存在すると仮定する
usersモデル、postsモデルの2テーブルある
postsモデルはusersモデルに紐づいている

## preload
二つのクエリを発行し、関連するモデルを取得する
クエリをモデルごとに発行するため、where旬の条件としては使えない
JOINをするわけではないので、条件を指定しないのであれば、比較的軽量

“`
users = users.all.preload(:posts)

上記は、usersに対してのall、usersに紐づくpostsの取得、この二つのクエリを発行している
“`

## eager_load
関連するモデルに対して、LEFT OUTER JOINする
JOINするため、条件として使用可能
大規模なテーブルになった場合、JOINする数が多くなり、複雑になり、パフォーマンスに影響する可能性あり

“`
users = users.all.eager_lo

元記事を表示

【Rails】carrierwaveでローカルに保存したファイルをアクションを経由して取得する

## はじめに
carrierwaveでpdfファイルを投稿し、そのファイルをクリックするとファイルを開く機能があります。
今回は、ファイルをローカル上のpublicディレクトリに保存しているためurl直打ちでファイルでのファイル表示の対策のために、保存先をpublicディレクトリから変更し、ファイルのパスから取得するのではなくアクション経由で取得する方法に変更してurl直打ちで表示するのを防ぐ対応をしました。
carrierwaveでのファイルの投稿機能などについては今回のテーマの趣旨とは違うため省略します。

## 環境
`Rails 7.0.4`

## テーブル
| Posts |
|:———–|
| name |
| file |

## コントローラー
~~~ruby:app/controllers/posts_controller.rb
def show_file
file_path = Rails.root.join(‘uploads’, ‘post’, ‘file’, params[:id], “#{params[:file

元記事を表示

Railsにおける複数形`s`の注意

# はじめに
めちゃくちゃつまづいた理由が「複数形`s`」にあったので、
戒めと教訓の思いを込めて、「複数形に気を付けようね!」という記事です。
# 問題
`routes.rb`にて、`resource :login …`と書くべきところを、
`resources :login …`と書いてしまい
`id`必要だわ`spec`は通らないわ、
GPTに聞いても「`login`を`logins`と書いてください」と解決にならない解決策(私が悪い)。
大変でした。
# 気を付けるべきところ
## `resource`と`resources`は別物
> ### `resources`
>
> – `resources`は、複数のリソースを扱う際に使用されます。一般的には、複数のオブジェクトの集合に対するCRUD(Create, Read, Update, Delete)操作を行う場合に使います。
> – 例えば、`resources :users`と記述すると、ユーザーの一覧表示(index)、新規作成(new)、表示(show)、編集(edit)、更新(update)、作成(cre

元記事を表示

データを取得するために、何気なく使用していた、findメソッド・whereメソッドそれぞれから得られる結果の違いについて

## バージョン
– ruby 3.2.2
– Rails 6.1.7.6
————————-

データを取得するために、深く考えずに使用していたfindメソッドとwhereメソッド。だが、スクールで課題に取り掛かっていた時に、得られる結果に奥深い違いがあることを知り、追求したくなったので、とりあえず現時点でわかったことをまとめたいと思います。

今回、tasksテーブルが以下のように定義されている。
|name|content|created_at|updated_at|以下、関係ないので省略…|
|:-:|:-:|:-:|:-:|:-:|

## あるタスクの内容(content)のデータを取得しようとwhereを使ったら、エラーになった!!なぜだ!!

`task.content` という形で、あるタスクの内容のデータを取り出すために、まず、
`task = Task.find(39)`として、idが39のデータを取り出そうとしたが、この日の私は、最近findばかり使用しているから、whereにも慣れたいなと考え、whereを用いてデータを取得

元記事を表示

Stimulus アプリケーションの起動時に何をしているのか?

# はじめに

私は、StimulusをRailsで使うとき、[stimulus-rails](https://github.com/hotwired/stimulus-rails) gemをインストールします。
そして、以下のコマンドを実行してStimulusを使う環境を整えます。
“`sh
./bin/rails stimulus:install
“`
このコマンドを実行すると、複数のファイルが作成されます。
このファイルがあるおかげで、Stimulusが気軽に使える状態になります。

作成されるファイルの中に、Stimulusアプリケーションを起動している以下のファイルがあります。
“`js:app/javascript/controllers/application.js
import { Application } from “@hotwired/stimulus”

const application = Application.start()

// Configure Stimulus development experience
application.debu

元記事を表示

devise_token_authで作る認証機能

## devise_token_authとは?
devise_token_authはRailsでトークンベースの認証機能を作れるgemのこと。
フロントとバックを分けて開発している時なんかに使う。
クライアントは、発行されたトークンを用いてユーザー認証を行う。
メールアドレスを用いた本人確認や、パスワードのリセットといった、webアプリケーションによくある機能もこのgemで作ることができる。

## 実行環境
Ruby 3.3.0
Rails 7.0.8

## 環境設定
まずは必要なgemをインストール。
“`
gem ‘devise_token_auth’
gem “devise”
gem “rack-cors”
“`
“`
bundle install
“`
:::note info
CORSの制御のため、rack-corsも必要
:::

deviseとdevise_token_authをインストール
“`
rails g devise:install
rails g devise_token_auth:install User auth
“`
:::note in

元記事を表示

Ruby 3.3.0 Rails 7.1.3 でYJITを有効にする

あるWebアプリケーションの Ruby on Rails のバージョンを`7.1.3`に上げました。 Ruby のバージョンを`3.3.0`に上げました。

ついでにYJITを有効にしました。
[Enable YJIT · pubannotation/pubannotation@f9284cd](https://github.com/pubannotation/pubannotation/commit/f9284cd97a57af10e05b33360c0c45634749a97e)
次のファイルを追加しました。

“`ruby:config/initializers/enable_yjit.rb
if defined? RubyVM::YJIT.enable
Rails.application.config.after_initialize do
RubyVM::YJIT.enable
end
end
“`

運用中に何かの理由で無効にしたくなったら、コメントアウトするかファイルごと削除します。
この方法は、最新のRuby on Railsに取り込まれているそのま

元記事を表示

RailsとNext.js:ウェブ開発の二つの異なるアプローチ

ウェブ開発の世界は広く、さまざまなツールやフレームワークが存在します。

この記事は、2つの人気のある技術、Ruby on Rails(通称「Rails」)とNext.jsについて、それぞれの特徴や利点をまとめています。

## Ruby on Rails(Rails)とは?
Railsは、Rubyというプログラミング言語で書かれたサーバーサイドのウェブアプリケーションフレームワークです。2005年に登場して以来、多くのウェブサイトやアプリケーションで使用されています。

**Railsの特徴と利点**

– 規約重視のフレームワーク: Railsは「Convention over Configuration(設定より規約)」の原則を採用しており、開発者が一般的な決定やパターンを迅速に進めることができます。
– 全スタック開発: Railsはデータベース、ウェブサービス、ウェブページなどの全てを扱うことができ、一貫した開発体験を提供します。
– 豊富なジェム: Rubyのライブラリ(ジェム)は非常に豊富で、多くの機能を簡単に組み込むことができます。
大規模なコミュニティ: 長年の歴史と

元記事を表示

【Rails】DeviseやDevise Token Authのyield部分に処理を追加する方法

## はじめに
[Devise](https://github.com/heartcombo/devise)や[Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth)のコードの中に以下のように記述されている箇所があります。

“`rb
def create
# …
yield resource if block_given?
# …
end
“`

https://github.com/heartcombo/devise/blob/e2242a95f3bb2e68ec0e9a064238ff7af6429545/app/controllers/devise/confirmations_controller.rb#L12

この`yield resource if block_given?`の部分に処理を追加する方法について記載します。

## 方法

オーバーライドの際に以下のように記述することで該当部分に処理を追加することができます。

“`rb

元記事を表示

AWS SDK for Rubyを使ってCloudWatch Logs Insightsの分析内容を取得する

# はじめに
CloudWatchのログの内容が膨大なときはCloudWatch Logs Insightsを使って必要なログのみを取得し分析していたのですが、AWS SDK for Rubyを使ってCSV形式で出力する機会があったのでその方法についてまとめてみました。

CloudWatch Logs Insightsをあまり使ったことがない方、CloudWatchのログデータをCSV形式で取得する方法について興味がある方のお役に立つかと思います!

# CloudWatch Logs Insightsとは?
独自のクエリ構文を使いCloudWatch Logsのログデータをインタラクティブに検索、分析できるAWSが提供するサービスの一つです。

:::note info
CloudWatch Logsとは?
CloudWatchの機能の一つで、AWSのリソースやアプリケーションから生成されるログデータを収集、監視、保存する
:::

CloudWatchのサイドバーから「ログのインサイト」に進むと操作画面に移ります。

![image.png](https://qiita-imag

元記事を表示

RoRにおける検索時の表記揺れ対応(漢字、カタカナ、ひらがな)

## 事象

検索機能を実装する際、表記揺れに対応する必要が生じました。例えば、検索ワードが「東京」の場合、「とうきょう」や「トウキョウ」といったひらがなやカタカナ表記でもヒットさせる必要がありました。また、「コンビニ」というカタカナで入力された場合には、「こんびに」というひらがな表記での検索にも対応することが求められました。この記事では、Ruby on Railsを使用して、これらの表記揺れに柔軟に対応する方法を共有いたします。

また、このアプローチは、「漢字のみ」「カタカナのみ」「ひらがなのみ」といった通常のパターンだけでなく、「漢字とカタカナとひらがな」「漢字とカタカナ」「漢字とひらがな」「カタカナとひらがな」といったイレギュラーなパターンに対しても柔軟に対応できます。これは、各文字が漢字、カタカナ、またはひらがなかどうかを個別に判断し、それに応じて適切な変換を行うことにより実現されています。この方法により、多様な表記揺れに対応することが可能になり、検索機能の精度を高めることができます。

## 対処法

以下のコードスニペットでは、RubyのStringクラスにStringH

元記事を表示

devise_token_authの設定について

## deviseとは

deviseは、Railsで簡単にログインやサインアップなどの認証機能を実装することができるgemの事です。

## devise_token_authとは

devise_token_authとは、トークン認証機能を実装することができるgemです。
例えば、ユーザーがログインした時にサーバー側でトークンが生成されてそれを、Headerに含めてユーザー側にレスポンスすることができます。

## devise_token_authの導入
まずは、必要なgemをGemfileに書いていきます。
“`diff_ruby:Gemfile
+ gem ‘devise’
+ gem ‘devise_token_auth’
“`
次に、gemをインストールします。
“`
bundle install
“`
インストールが完了したら、devise用のファイルを以下のコマンドで作成します。
“`
rails g devise:install
“`
“`
rails g devise_token_auth:install User auth
“`
上記のコマンドに

元記事を表示

【Ruby on Rails】Active StorageがうまくAttachmentされずに苦しんだ話

# はじめに
Ruby on RailsでECサイトを作成する課題に取り組んでいたところ、Active Storageでattachした画像が何度やってもnilになってしまい苦しみました。
私のような稀有な現象に悩む方のために記事として残しておきます。

# 原因
原因はActive StorageがAttachmentする対象テーブルでデフォルトの連番idを使用しなかったことでした。
テーブルを作成した際に「id」カラム、「created_at(作成日時)」カラム、「updated_at(作成日時)」カラムは自動で作成されます。
しかし、今回作成する商品テーブルでは商品IDを使用するため、自動採番される値ではなく、こちらで決めたユニーク値を設定しました。
Active Storageが作成した「active_storage_attachments」テーブルは連番idを参照しているため紐づけることができずnilが渡されることが原因でした。
## 例
### AttachmentされないDB
#### item テーブル
|id|name|price|description|create

元記事を表示

.to_h について

### .to_hメソッドとは
対象のオブジェクト(配列やEnum型)に対してhashの形に変換する

#### 例
“`
users = [[:name1, Alice], [:name2, Bob], [:name3, Hanako]]
users.to_hash
→{name1: Alice, name2: Bob, name3: Hanako}
“`

元記事を表示

gem `better_errors` の使い方【Ruby on Rails】

# はじめに
`bettr_errors`はRubyのgemで、特にRails開発において有用なツールだそうです。
コマンドを覚える必要もなく、開発環境においては入れるだけ得!なgemです。
# 使い方
特徴
– 詳細なエラーページを表示してくれる
– エラーが発生した場所でコードを試行できる
– エラーが発生した時点の変数を確認できる
– エラーが発生したソースコード周辺を表示してくれる

以上の特徴により、問題の原因を突き止めやすくなります。
## インストール
### 1. `Gemfile`に追記
“`rb
group :development, :test do
# …省略

gem ‘better_errors’
gem ‘binding_of_caller’

# …省略
end
“`
`binding_of_caller`は、エラーが発生したコードの呼び出し元も教えてくれるgemです。
`better_errors`と一緒に使用されることが多い。
### 2. 追記したgemのインストール
“`bash
$ docker compose r

元記事を表示

sort_byメソッドについて

## sort_byメソッドについて

array,hashに対して使えるメソッド
ブロックに渡した、値をソートキーとし昇順に並び替えて返す
:::note info
ここで言う、ソートキーとは、要素に紐づけた値
数字だと、そのままの値がキーとなりなんの意味これ・・・?と思うが
lengthなどで考えてみるとわかりやすい
appleという値が飛んできた時に、こいつは5っていうソートキーを基準に比較するで・・・的な感じ
:::

このメソッドは破壊的なメソッドではないため、元のarray,hashを変更しない
変更をしたい場合は、sort_by!を使用する

“`
### arrayの場合
const nums = [3, 2, 1, 4, 5]
nums.sort_by { |num| num }
→[1, 2, 3, 4, 5]

### hashの場合
const ages = [{age: 1}, {age: 5}, {age: 3}]
ages.sort_by {|hash| hash[:age]}
→[{age: 1}, {age: 3} {age: 5}]
“`

元記事を表示

OTHERカテゴリの最新記事