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

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

君、Railsでeager_loadした後の行でfind_by, where使ってないか?

# Railsでeager_loadした後の行でfind_by, where使ってない?

## 要約
`eager_load`や`preload`でデータを読み込んだ場合、以降の行で`find_by`, `where`を使うとクエリを発行してしまう(ロードしたデータを利用しない)

#### 【背景】
別件でサーバーの不具合原因を調査していると、eager_loadした後にも関わらずクエリが発行されていることを発見
#### 【実行環境】
|技術スタック|バージョン|
-|-
|Ruby|3.2.2|
|Rails|7.0.4|
|Postgresql|1.1|
## 具体例 (NG)
#### シナリオ
1. ログイン中のユーザーに紐づく投稿(posts)を取得し、その投稿に紐づくコメント(comments)を事前読み込み
– has_manyとかで関連づいているとする
2. 前ステップで取得した各投稿に対して紐づくコメントの中から、
`user_id: 5`
のレコードを検索

“`ruby
# current_userは事前にUserテーブルから取得し

元記事を表示

Kaigi on Rails 2024に参加して、自分なりのカンファレンスの楽しみ方が見えてきた気がする

# Kaigi on Rails 2024に参加してきました

Gakken LEAPで働いていますkoboriです。普段はShikaku Passというオンライン学習サービスの開発を行っております。2024/10/25~26で開催されたKaigi on Rails 2024というテックカンファレンスへ現地参加してきました。

今年の5月のRubyKaigi2024へは会社制度を利用して参加し、本ブログのエントリーとしても公開しました。今回も会社制度を利用することはできたのですが、個人の趣味として参加することにしてみました。今回参加してみて、趣味ゆえの気楽さによるものか、自分なりのカンファレンスの楽しみ方が見えてきた気がしています。今回は、その過程で試したことや考えたことを中心に記事にしていきます。恐らく、私と同じようにカンファレンス参加経験が浅い方に向けた内容になるかと思います。

また、最初に断りを入れておきますが、この記事は会社支援による参加を否定する意図もなければ、個人の趣味による参加を推奨する意図もありません。よろしくお願いします。

# Kaigi on Rails 202

元記事を表示

【Rails】furimaアプリ 商品購入機能 #1

# 実装概要
商品をクレジットカード決済で購入する機能を実装から単体テストまで行う

### 事前準備 Turbo機能をオフにする
“`ruby:views/items/show.html.erb
# 中略

~data: { turbo: false }~%>

# 中略
“`
PAY.JPを使用するためには、Turboの機能をオフにする必要があるため上記コードを追記

### Purchasesコントローラーの作成
ターミナル
“`
% rails g controller purchases
“`

### indexアクションの定義
“`ruby:app/controllers/purchases_controller.rb
def index
end
“`

### ルーティングの設定
“`ruby:config/routes.rb
# 中略
resources :purchases, only: :index
“`

### 購入、送付先住所についてのモデルとテーブルの作成
ターミナル
“`
% rails g model purchese
% rails

元記事を表示

【Rails】無駄なスペースや全角文字を半角に変更して保存する方法

ユーザーにデータを入力してもらう際に、保存する内容(形式)を統一したいなと思った時に下記の設定が役に立ちました。

“`rb:app>models>application_record.rb
class ApplicationRecord < ActiveRecord::Base self.abstract_class = true before_validation :normalize_attributes private def normalize_attributes attributes.each do |key, value| if value.is_a?(String) self[key] = value.tr("0-9", "0-9").gsub(/[\s ]+/, "") end end end end ``` 処理の内容 ```rb attributes.each do |key, value| ``` attributes.each は、モデルのすべての属性(カラム)とその

元記事を表示

Rspecのエラー: undefined method `include’ for an instance of RSpec::Expectations::ValueExpectationTarget

非常に初歩的なミスだが、戒めのための備忘録

Userモデルの`first_name`には`validates :first_name, presence: true`というバリデーションがかけられており、バリデーションが正しく動いているかテストしたかったので、バリデーションをかけた際に以下のようにオブジェクトにエラーメッセージが含まれるか確認するための非常によくあるテストを書いた

“`ruby
it “is invalid without a first name” do
user = User.new(
first_name: nil,
last_name: “Sumner”,
email: “tester@example.com”,
password: “dottle-nouveau-pavilion-tights-furze”
)

expect(user.errors[:first_name]).to include(“can’t be blank”)
end
“`

上記のspceを実行したところ以下のようなエラーが出た

元記事を表示

【Next.js/Rails】Next.js、RailsでCookieによるログイン認証を行う時にハマったこと

## はじめに
フロントエンドにNext.js、バックエンドにRailsを使用した構成で、Cookieを使った認証時に発生した問題とその解決方法をメモとしてまとめました!

## 結論
結論を先に言うと
Next.jsのApp Routerを使用した場合、サーバーサイド(Rails)へのリクエストはNode.jsから送信されるため、クライアント側で保持されているCookieが正しく含まれないことがあります
これを解決するためには、cookies()関数など使用してサーバーサイドでCookieを取得し、リクエストヘッダーに設定する必要がありました

## 問題
– フロントエンドでログイン後、データを取得しようとすると、認証エラー(401 Unauthorized)が返却される
– Postmanでは正常に動作する
– RSpecでの認証に関するテストはパスしている

### サーバー側の処理
**関係箇所のみ抜粋**(Deviseなどのgemは使用していません)

“`ruby
class SessionsController < ApplicationController sk

元記事を表示

rails: 備忘録

## postgresql のデータベースホストに関する 環境変数は DB_HOST ではなく ”PGHOST” である。

$ export PGHOST="hogehoge"

とすべし。  .env に至っても同様。
ただし、config/database.yml では ただの “host” である。
そもそも sqlite3 だけで十分だという話になってはいるが・・・
postgresqlでの DBでスタートする際は、 ほとんど記事がなく、これも
偶然探り当てたもの。意外にハマるのであった。

以上

元記事を表示

【Ruby on Rails × TMDB API × Mecab × AWS】ユニークなあらすじから映画を発掘するポートフォリオPlotForgeを作成しました!

### はじめに
初めまして、はしと申します。
バックエンドエンジニアを志して転職活動中です。

この度、ポートフォリオ「[PlotForge](https://plotforge.net/users/sign_in)」をリリースしましたので、投稿いたします!

https://plotforge.net

映画が好きなので、映画の発掘ができるアプリを作成してみたいという思いから作成しました。

#### きっかけは??
YouTubeの映画紹介ショートです。
「⚪︎⚪︎な映画挙げてけw」のようなショートで知らなかった映画のことを
どんどん知ることができ実際に鑑賞すると面白かったので、
映画を知る機会を広げるアプリを作りたいと思いました。

#### どんなアプリ?
ランダムに呼び出された映画からユニークなあらすじが作成することができます。
![plotforge_introduction_qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606327/7136a927-1df4-6afb-82

元記事を表示

Railsでのレコードのランダム抽出

始めまして、現在プログラミングスクールRUNTEQで学習中である初学者の[massan](https://qiita.com/massan-E/questions)です。

今回は自分が制作中のミニアプリで実装しようとしたコードについて深掘りした結果
RailsのActiveRecordやDBについての学びがあったので、自分の振り返りも兼ねて記事にしてみました。

# 今回やりたかったことと前提条件

今回自分が考えていたのは、Railsでのレコードのランダム抽出機能でした。
具体的には、ユーザーが掲示板を投稿し、その掲示板に対して他のユーザーが投稿したコメントの中からランダムで一件抽出する。というものです。(Xのポストに対する返信の中から一件ランダム抽出するような感じ)

前提条件となるそれぞれのテーブルの関係は以下です

“`Ruby:app/models/board.rb
class Board < ApplicationRecord validates :title, presence: true, length: { maximum: 255 } validates

元記事を表示

【Rails】Rails APIを用いたグループ機能実装:グループ作成とユーザーの入退会処理

Rails APIでUser周りの実装をしたので、グループの作成とユーザーの入退会処理をしていきます。
[【Rails】JWTを用いたUser周りのAPI実装](https://qiita.com/kay903347/items/3847a5cf4642e122128c)
## Groupテーブル
| カラム名 | データ型 | 制約 | 説明 |
| — | — | — | — |
| id | integer | 主キー、オートインクリメント | グループの一意な識別子 |
| name | string | null: false | グループ名 |
| created_at | datetime | null: false | レコード作成日時 |
| updated_at | datetime | null: false | レコード更新日時 |
## GroupMembershipテーブル
| カラム名 | データ型 | 制約 | 説明 |
| — | — | — | — |
| id | integer | 主キー、オートインクリメント |

元記事を表示

【Rails】polymorphicリレーションとhas_and_belongs_to_many

### 【Rails】polymorphicリレーションとhas_and_belongs_to_many

Railsには、モデル同士の関係を設定するリレーションの仕組みがあります。その中でもpolymorphicリレーションとhas_and_belongs_to_many(HABTM)リレーションは、多対多の関係を表すリレーションです。ただし、用途や機能が異なるため、使い分けが大切です。この記事では、それぞれのリレーションの違いや使い方について解説します。

### 1. has_and_belongs_to_many(HABTM)リレーション

has_and_belongs_to_many(HABTM)は、「多対多」のリレーションを定義する方法の1つです。2つのモデルが対等な関係でお互いに関連し合うことを表します。

使用例:コースと学生の関係

例えば、1人の学生が複数のコースを履修し、1つのコースに複数の学生が参加するという関係は、多対多の関係に当てはまります。この場合、StudentとCourseのモデルにHABTMを設定します。
“`rb
class Course <

元記事を表示

【Rails】Rails APIでログイン、ログアウト

前回、Rails APIでUser周りの実装をしました。
[【Rails】JWTを用いたUser周りのAPI実装](https://qiita.com/kay903347/items/3847a5cf4642e122128c)
その記事のログイン、ログアウトで気になったことをまとめます。
先にmodel、controllerを貼り付けておきます。
“`ruby:models/usr.rb
class User < ApplicationRecord before_save { self.email = email.downcase } validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAI

元記事を表示

【Rails】Rails APIで新規登録、退会処理

前回、Rails APIでUser周りの実装をしました。
[【Rails】JWTを用いたUser周りのAPI実装](https://qiita.com/kay903347/items/3847a5cf4642e122128c)
その記事の新規登録、退会処理で気になったことをまとめます。
先にmodel、controllerを貼り付けておきます。
“`ruby:models/usr.rb
class User < ApplicationRecord before_save { self.email = email.downcase } validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL

元記事を表示

scopeをif文のように使う

## 初めに

疑問に思ったことや上手くいかなかったことのアウトプットをしています。
自分なりの理解でアウトプットしていきます。初学者なので誤りもあると思います。
その際はご指摘いただけると幸いです。

## scopeでのwhereの役割
whereはデータベースからレコードを絞り出す役割がありますが、
フォームから送信されてまだ保存されていないレコードも保存できます。

**この絞り出す機能が、結果的にif文のような役割を果たします。**

## scopeにおいての比較演算子を使用する際の注意点
“`
scope :exampled, -> { where(‘aaa_at <= ?', Time.current) } ``` のように、 ``` scope :exampled, -> { where(‘aaa_at <= Time.current') } ``` と書かないのは、理由があります。 1.SQLインジェクション対策 直接値を埋め込むと、意図しないSQLコードが実行される恐れがあります。 2.時間の評価 'aaa_at <= Time.current'と書くと T

元記事を表示

自動的にエスケープされる

# 5.1 安全な出力
>5.1.1 開発の動機
`HTMLテンプレートにデータを挿入する方法は、きわめて慎重に設計する必要`があります。たとえば、`@review.titleを何の工夫もなくそのままHTMLに式展開するようなことは絶対にすべきではありません`。もしこのレビューのタイトルが仮に「Flanagan & Matz rules!」だとしたら、出力はwell-formedになりません。well-formedにするには、&->&のようにエスケープしなければなりません。さらに、ユーザーがレビューのタイトルに細工をして、悪意のあるHTMLをタイトルに含めれば、巨大なセキュリティホールになる可能性すらあります。このリスクの詳細については、セキュリティガイドのクロスサイトスクリプティングの節を参照してください。
* `@review.title`をHTMLに展開してはならない。

>5.1.2 安全な文字列
`Active Supportには「(html的に) 安全な文字列」という概念`があります。安全な文字列とは、`HTMLにそのまま挿入しても問題がないというマークが付けられ

元記事を表示

RailsアプリをRDSと連携させてECSにデプロイする

## 1.AWSアカウントIDの設定
アカウントIDを環境変数に保存し、後の操作で使用できるようにします。

“`bash
export ACCOUNT_ID=$(aws sts get-caller-identity –query Account –output text)
“`

## 2.IAM関連
ECSタスクがCloudWatchなどの他のAWSサービスにアクセスするためのロールを作成します。

“`bash
cat << EOF > trust-policy.json
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: {
“Service”: “ecs-tasks.amazonaws.com”
},
“Action”: “sts:AssumeRole”
}
]
}
EOF
“`

“`bash
aws iam create-role –role-name hello-world-rails-rdb-task-execution

元記事を表示

【Rails】JWTを用いたUser周りのAPI実装

Rails APIでUser周りの実装をしていきます。User周りの実装は基本的なアプリでは必須になってくると思うのでぜひ参考にしてください。
Docker環境上で開発しています。
のちに同じプロジェクト内で管理画面を開発することを考えたため、Rails APIでは開発していません。
駆け出しエンジニアですので間違っているところはコメントください。
## Userテーブル
Userテーブルは以下の設計にしました

| カラム名 | データ型 | 制約 | 説明 |
|————–|—————|—————————|—————————–|
| id | integer | 主キー、オートインクリメント | ユーザーの一意な識別子 |
| name | string | null: false

元記事を表示

【初心者向け】find と find_by の使い分け

# はじめに
find と find_by は、どちらもRailsでレコードを取得するためのメソッドで似ていますが、少々動作や使い方に違いがあります。
それぞれ解説していきます!

# find
### 概要
プライマリキー(通常は id カラム)を指定して、1つのレコードを取得します。

### エラーハンドリング
指定した id に該当するレコードが見つからない場合は、ActiveRecord::RecordNotFound 例外が発生します。

### 使い方
“`
user = User.find(1)
“`
User.find(1) は、 id が 1 のユーザーを取得します。
idが1のユーザーが存在しない場合、ActiveRecord::RecordNotFound例外エラーが発生します。

# find_by
### 概要
任意のカラムに基づいて条件を指定し、最初に一致するレコードを取得します。

### エラーハンドリング
指定した条件に一致するレコードが見つからない場合は、nil を返します(例外は発生しません)。

### 使い方
“`
user = Us

元記事を表示

XSSの攻撃点とは

試しにXXSをやってみたい。

# どうするのか?
* 悪意のコードをサイトに仕込み、閲覧したユーザーが実行させられる
* どうやってサイトに仕込むのか?

>検索のキーワードの表示画面や個人情報登録時の確認画面、掲示板、ウェブのログ統計画面等、利用者からの入力内容やHTTPヘッダの情報を処理し、ウェブページとして出力するものがあります。ここで、`ウェブページへの出力処理に問題がある場合、そのウェブページにスクリプト等を埋め込まれて`しまいます。

https://qiita.com/masatom86650860/items/e3d28d15f9304d09389a#152-html%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E5%85%A5%E5%8A%9B%E3%82%92%E8%A8%B1%E5%8F%AF%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E5%AF%BE%E7%AD%96:~:text=%E6%A4%9C%E7%B4%A2%E3%81%AE%E3%82%AD%E3%83%

元記事を表示

【個人メモ】Ruby on Rails チュートリアル 第8章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです

# 個人メモ
– Sessionを設定することでコンピュータ間(ユーザーのパソコンのWebブラウザとRailsサーバーなど)を半永続的に接続することが可能
– cookies
ユーザーのブラウザに保存される小さなテキストデータのこと
Cookiesを保存場所とすることでセッション機能を実現する
– form_with(url: login_path, scope: :session)
セッションではSessionモデルがなく、そのためsessionインスタンス変数に相当するものがない
したがって、form_withヘルパーにはscopeとurlを指定する必要がある
– Rubyではnilとfalse以外のすべてのオブジェクトは、真偽値ではtrueになる
– flash.nowのメッセージはその後リクエストが発生したときに消滅する
– 全コントローラの親クラスである「Applicationコントローラ」にセッションヘルパーをincludeすることでどのコントローラからでもメソッドを呼び出せる

元記事を表示

OTHERカテゴリの最新記事