Ruby関連のことを調べてみた2021年09月18日

Ruby関連のことを調べてみた2021年09月18日

N+1問題について!

N+1問題とは、、、?

初心者ならではの視点でわかりやすく書いていきたいと思います!

# ①.N+1問題の意味!

N+1問題とは、アソシエーションを利用した場合に限り!!

データベースへのアクセス回数が多くなってしまうと言う問題です!

これはアプリケーションのパフォーマンス低下に繋がります。。。

例えば!通常、コントローラーで  mail.allなどでデータを取得する際は、1度のアクセスで済みます!

しかし例のような、メールが複数存在する一覧画面に、それぞれユーザー名を表示するケースを考えてみます!

この場合、mailsに関連するusersの情報の取得に、メール数と同じ回数のアクセスが必要になってしまいます!

もしも1億メールあれば、1億回以上アクセスすることになり、アプリケーションのパフォーマンスが著しく下がることになるということです!

これを解決するために、includesメソッドを利用します!

# ②.includesメソッドの使用方法!

includesメソッドは、引数で指定された関連モデルを1度のアクセスでまとめて取得してくれます!

記述は、inc

元記事を表示

Rubyで時間の差(HH:MM:SS)を計算する

時間の差をHH:MM:SSとして欲しい時に、変換する際にJSTとして+9:00されてしまって困ったので備忘録

こんな感じ↓
6時間10分ー4時間=11時間10分(JST)+9:00

足し算引き算はunixtimeで数字として行う(これは他に記事いっぱいあるのでそっち見て)

“`ruby
# 時間の差を見たいので引き算
diff = Time.zone.at(unix_base_time) – Time.zone.at(something_unix_time)
p diff.class # FloatとかActiveSupport::TimeWithZoneならいけることを確認した
p Time.zone.at(diff).strftime(‘%H:%M:%S’) # “09:10:00”
p Time.zone.at(diff).utc.strftime(‘%H:%M:%S’) # “02:10:00”
“`

元記事を表示

?インターネット老人?のためのホームページ(死語)リフォーム術

# この記事の対象
~00年代初頭にホームページ作っていて、現在放置中……という人、あるいはそういう人から依頼されて昔のフォルダを受け取った人が対象になります。
スキル的にはjQuery(Bootstrap)なら何とか勢~(バックにも関心がある)SPA初心者勢を想定しています。

# 手順
## 1.本当に自前でやる必要があるか考える
Webサービスが氾濫する現在、現在サイトにある機能を本当に自前で提供する必要があるか考えましょう。

### 日記
まぁ**最有力はブログへの移行**ですね。黒歴史を消す人も多いですが、逆に過去の日記みたいなもんで、残しておきたいと思う人もいるかと思います。ていうかホームページは放置してて日記にあたる部分だけ流石にブログに移行してる人も多いかと思いますね。
何らかの理由でブログに移行できない、不適切だと思う場合はスクレイピングして文章データをmdやらjsonに纏めて、今流行りのGatsbyあたりに手を出すのも良いのではないでしょうか。

### イラスト
これは現行のシェアとしてもシステム的にも**[pixiv](https://www.pixiv.ne

元記事を表示

[Ruby] AtCoder過去問 B – Nice Shopping

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_b

##B – Nice Shopping
はじめに入力を受け取ります。
今回は少し面倒でした。

“`ruby
a, b, m = gets.split.map(&:to_i)
a_ary = gets.split.map(&:to_i)
b_ary = gets.split.map(&:to_i)
m_ary = []
m.times do |i|
m_ary << gets.split.map(&:to_i) end ``` 割引券の配列m_aryの中は配列の中に配列を入れています。m_aryの中のそれぞれの配列が割引券一枚の条件を示しています。 割引券を使わずとも一番安い組み合わせが存在する可能性がありますので、price_aryという配列を作って代入しておきます。 ```ruby a, b, m = gets.sp

元記事を表示

fakerを使って投稿に対してのダミーコメントを作ってみた

現在投稿系のアプリを作成しており、1投稿に対してコメントを複数つけるようにしました。
そこでコメントが少ない場合なら良いのですが増えてきたときにコメントを見るために下までスクロールしないといけなくなります。
自分がユーザーでも面倒くさいので他の方法を考えました。

2つ考えてみました

1つ目の方法は
(クリックしてコメントを表示)みたいなボタンを作ってボタンがクリックされたら表示する。という動作です
これはjavascriptを使って実装できると思いました。
普段は@commentを(display:none)で消しておいて、onclickでshowさせるみたいにできるはずです。

以下のサイトが参考になると思います。

https://into-the-program.com/display-block-none/

2つ目の方法は
gem ‘kaminari’ を実装して、設定した数だけ表示して他の要素はページを切り替えることで見れるようにすることです

↓こんな感じ

![スクリーンショット 2021-09-17 17.38.22.png](https://qi

元記事を表示

extend Activesupport::Concernについて

concernsに定義するモジュールでよく書かれているがいまいち何をしているのかよくわかっていなかったので調べました。

### 結論
単純に言えば、`モジュールでのクラスメソッドの定義やそれをincludeする側でクラスメソッドとして追加する方法、クラスレベルでのメソッド呼び出しの容易な方法を提供してくれるもの`だと理解しました。

### 具体例
具体例は以下のページと同じものです。
https://api.rubyonrails.org/v6.1.4/classes/ActiveSupport/Concern.html

例えば、モジュールがincludeされたときに特定の処理を呼び出したり、モジュールのメソッドをクラスメソッドとして追加したい時、通常以下のように書きます。

“`ruby
module M
# https://docs.ruby-lang.org/ja/latest/method/Module/i/included.html
def self.included(mod)
# includeする側(例えばクラス)の特異メソッドとしてClassM

元記事を表示

要素の最後を求める時

◼️ famiry = [“suzuki”, “takurou”, “gou”,・・・・ “qiita”]
例えば上記の様な配列があったとする。最後の要素だけを取り出す時、suzuki 君から順に最後まで数えてqiita君の順番が98番だった時、puts famiry[98] と書き出力するのはそごくめんどくさい。

◼️ こんな時、こんな問題を解決するのが [配列の要素数 -1]を使うこと。
書き方: famiry[famiry.lenght -1 ]
     puts famiry

上記の様な書き方を行うことで全体の要素数から最後の値ふだけを出力できる。そして、数えるみたいなめんどいことはやらなくておくなる。

今日の投稿は以上です。

wagaでした!

元記事を表示

エラー:No route matches [GET] “/new_user_session_path”

##環境
MacOS BigSur Ver11.5.2
Ruby 3.0.2
Rails 6.1.4.1

##状況
Railsアプリを実装中、下記のエラー発生

“`
No route matches [GET] “/new_user_session_path”
“`

一見問題なさそう

“`app/views/layouts/_header.html.slim
li
= link_to ‘ログイン’, ‘new_user_session_path’
“`

pathを確認したけど間違ってない

“`
$ rails routes

new_user_password_path GET /users/password/new(.:format) devise/passwords#new

“`

##解決方法
#####原因:pathを””で囲っていた…
初歩的なミスすぎて自分で自分に引きました

“`app/views/layouts/_header.html.slim
li
= link_to ‘ログイン’, new_user_session

元記事を表示

Ruby on Ralis でデータベースにあるテーブルの中身を指定して取得してviewに表示する方法

データベースのテーブルの中身を指定して取得。

テーブル名:lists
カラム名:title

“`
def index
@lists = List.find_by(title:”リスト”)
@lists_number = List.find_by(number:46)
end
“`
あとはviewに記述すれば表示されます。

“`
<%= @lists.title %>
<%= @lists_number.title %>
“`

元記事を表示

エラー:Could not find ‘spring’ (= 2.1.1) among 167 total gem(s) (Gem::MissingSpecError)

##環境
MacOS BigSur Ver11.5.2
Ruby 3.0.2
Rails 6.1.4.1

##状況
RailsアプリをHerokuへデプロイした際に下記のエラーが発生

“`
Could not find ‘spring’ (= 2.1.1) among 167 total gem(s) (Gem::MissingSpecError)
“`

##原因
どうやらこのgemが悪さをしているらしい

“`ruby:Gemfile
group :development do
(略)
gem ‘spring’
gem ‘spring-commands-rspec’
end
“`

##疑問点
developmentだけのgemなのになぜデプロイ時にエラーが出るのか謎

##解決策
この2つのgemをコメントアウト

“`ruby:Gemfile
group :development do
(略)
# gem ‘spring’
# gem ‘spring-commands-rspec’
end
“`

bundle installも忘れずに!

元記事を表示

結合テストを書いていく①

#はじめに
単体テストコードはフリマアプリ作成時にしっかり書いたのですが、結合テストは書いていなかったのでオリジナルアプリでは書いていきたいと思います。

その中で学習したことをアウトプットとして投稿させて頂きます。

#単体テストと結合テストの違い(単体テストの場合)

単体テストは機能ごとにテストを行います。

例えばuserの単体テストコードの場合

“`ruby:user_rspec.rb
describe ‘ユーザー新規登録’ do
context ‘登録できるとき’ do
it ‘nickname,email,password,company_name,profession_idが存在する場合は登録ができる’ do
end
end
context ‘登録ができないとき’ do
end
end
“`

モデルやコントローラーの機能ごとに問題がないかバリデーションの挙動を確認します。

# 単体テストと結合テストの違い(結合テストの場合)
結合テストの場合はユーザーがアプリを使用する一連の流れを確認するものになります。

ホー

元記事を表示

reek での Repeated Conditional 警告への対処は継承か委譲を用いる

業務で主に Ruby On Rails での開発を行っていますが、そこで得た知見や、失敗への対応などについて記します。

今回は「reek から `Repeated Conditional` の警告を受けた」場合にどのように対処するか、についてです。

## 現状(要件)

[reek](https://rubygems.org/gems/reek) は Rubyプログラムの [コードの臭い](https://ja.wikipedia.org/wiki/コードの臭い) を検知するツールとして、弊社の開発でも活用しています。

その reek が発する警告の一つに [Repeated Conditional](https://github.com/troessner/reek/blob/master/docs/Repeated-Conditional.md) というものがありますが、以下のように「一つのクラス内で、同じ条件判定を繰り返し定義している場合」に起こるものとされています。

“`ruby
# https://github.com/troessner/reek/blob/mas

元記事を表示

未ログイン状態のユーザーを転送

今回は自分が最初よくわからなくて苦戦した部分です。

例を出すと、ログインしてない状態でも、「投稿する」ボタンの遷移先であるURLを直接入力すると、新規投稿ページにアクセスできてしまうという事。

一体どういうこと?って感じでした汗

わかりやすく言うと、URLに直接、新規投稿や編集のパスを入力すると遷移できてしまうと言うこと!
つまり、ログインもログアウトも関係なく誰でも出来てしまいます!

セキュリティみたいな物ですね^^;

そこで、今回は未ログインユーザーが投稿画面など直接アクセスしてきた際には、ルートパスに遷移するように設定を行います!

このような仕組みをリダイレクトと言い、例を出してcontroller.rbのすべてのアクションに対して、「もし、ユーザーがログインしていなかったらindexアクションにリダイレクトする」ような機能を実装をしてみます!

# 1.リダイレクトとは?

本来受け取ったパスとは別のパスへ転送する機能のことをリダイレクトと言います!
リダイレクトを利用すると、アクションに処理を持たせて実行した上で、そのパスのビューを返すのではなく別の意図したパ

元記事を表示

RailsのScaffoldを使って3分でwebアプリを作ってみる

Ruby on Railsのscaffoldを使って最速でwebアプリケーションを構築してみます。

#Scaffoldとは

まずはRuby on Railsのscaffoldとは何かについて解説します。

scaffoldとは、Railsに備わっているコマンドの1つで、ルーティングやコントローラー(controller)、ビュー(view)、モデル(model)とテーブル(データベース)の記述やファイルなどを自動で作成してくれるコマンドです。

本来、scaffoldは建築現場の足場やビルの窓を拭くときに使用される吊り足場を意味します。Ruby on Railsのscaffoldにおいても、アプリケーションの足場であるMVC(上記で紹介したModel-View-Controller)等を指し示し、それらを容易に自動生成できます。

つまり、scaffold を使用することで、コントローラーやモデルを作成する手間を省くことができます。

scaffoldを使って作成されるルーティングは、Railsが定める7つのアクションになります。(index・show・new・edit・creat

元記事を表示

【Ruby on Rails】Web APIの作り方を詳しく解説!

# はじめに
以前にこんな記事を投稿しました。
[【3分で出来る】Ruby on RailsでWeb APIの作成](https://qiita.com/ruemura3/items/4e99a968b18b49829301)

この記事で解説したように、Ruby on Railsは本当に優秀なフレームワークで、簡単なAPIだったら数分で作れちゃうんです。

しかし前回は3分で作ったAPIを実際に動かして試してみたというだけで、ソースコードの中身までは解説しませんでした。

今回はソースコードを見ながら、Ruby on Railsで作ったAPIが動く仕組みを見ていきます。

前回作成したAPIがある状態で解説を行うので、まだの方は上記リンクを見て作ってみてください。5つのコマンドを打つだけで終わります。

## 前提知識
– APIとは
– JSON
– HTTPリクエスト、レスポンス
– GET, POST, DELETE, etc…

## 環境
– ruby 2.6.5
– Rails 6.0.2
– macOS Catalina 10.15.3

# Rails APIの仕組み

元記事を表示

[Rails]Gemを使ってモーダル作成

# はじめに
本記事では、Gemを使ったモーダルの作成方法を記述します。

## 参考動画
ブックマークしているサイトがもろ見えになるので、上は切りました。
「決して」やましいものはありません。

![05adb4091ab2c978dffd22ddbd5045d2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/8bcc6b41-7ff5-2a27-ae1e-b4c7ebb3a7b4.gif)

# 流れ

`gem`のインストールです。

“`ruby
gem ‘data-confirm-modal’
“`
からの

“`
bundle install
“`
からの

“`application.js
// = require data-confirm-modal
コメントアウトでOK
“`

“`erb
<%= link_to food_path(food.id), method: :delete, data: { confirm: '本当に削除しますか?削除すると

元記事を表示

知っておきたいincludesの正体【Rails】

rails 6.0.2
ruby 2.7.1

# includesとは

N+1問題を起こさないように、関連テーブルのデータをキャッシュしてくれるメソッド。
しかし、関連テーブルのデータをキャッシュするといっても
一体どのようにして、データを取得してきているのだろうか。

実はincludesは、モデルの関連など見て以下のどちらかの最適とrailsが判断したメソッドを実行している。
(このrailsの判断が正しいとは限らない。*後述)

preload|eager_load|
—|—|
|関連ごとにSQLを発行してキャッシュ。 |left_joinを用いて、キャッシュ。|

preload、eager_loadがどの様なSQLを発行してるか見ていく。

以下の様なモデルがあるとする。

“`ruby:user.rb
class User < ApplicationRecord belong_to :country #国 has_many :posts #投稿 end ``` ## preload preloadは、関連ごとにSQLを発行してキャッシュする。

元記事を表示

【Rails】同名のパスのviewで表示するインスタンスを使い分ける

rails初学者によるポートフォリオ作成中の学びのアウトプットです。

#実現したい事
クイズアプリを作成中に複数のモードを全てquestionモデルとanswerモデルで賄いたい(ジャンルAのクイズ集とジャンルBのクイズ集を実装する)。下記の二つのページのようにnew_answer_pathからアクセスした時に異なるジャンルの問題が表示されるようにしたい。

(モードA)

ジャンルAの問題を表示

回答欄(answerモデルに保存される)

(モードB)

ジャンルBの問題を表示

回答欄

#実装の流れ
①questionモデルにmode_numカラム(integer)を追加して問題のジャンルを番号で識別するようにする。

②new_answer_path(mode_num: <識別番号>)とし、newアクションにmode_numを渡すようにする。

③newアクションで渡された識別番号からquestionモデルを検索するよう実装する。

#実際のコード

(②のステップから)
問題ジャンルAはquestion.mode_numを1に設定。
問題ジャンルBはquestion.m

元記事を表示

Rails の Custom Validator を RSpec で柔軟かつ簡単にテストする方法

# はじめに
カスタムバリデータのテストを RSpec で記述するにあたり、いくつかの技術記事を参考にしたが、どれも一部情報が欠けているものばかりだった。

そこで、カスタムバリデータのテストの書き方について、個人的につまずいた部分を解消したものをまとめておく。

# 目標
以下のようなカスタムバリデータがあり、そのテストコードを RSpec で記述できるようにする。

“`ruby:app/validators/inclusion_in_array_validator.rb
# frozen_string_literal: true

# 配列の中身に特定の値が含まれている、または、特定の値の範囲内かを検証するカスタムバリデーション
class InclusionInArrayValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) return if value.all? { |v| options[:in].include?(v) } rec

元記事を表示

[Ruby] AtCoder過去問 B – Chocolate

##はじめに
AtCoderの過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc092/tasks/abc092_b

##B – Chocolate

まずは入力を受け取ります。
aは配列として受け取るようにしています。
答えはチョコの数なので変数chocoに0を代入しておきます。

“`Ruby
n = gets.to_i
d, x = gets.split.map(&:to_i)
a = readlines.map(&:to_i)

choco = 0
“`

まずは法則を考えます。
私は割り算でこの問題を考えました。

①まず、dをそれぞれの日数で割った時あまりなく、ちょうどで割り切れた場合はチョコを割った答えがチョコを食べた数です。
→この法則は入力例2の一人目や入力例3の最後のひと(6の人)に当てはめて計算してみたらわかります。

②もし、dをそれぞれの日数で割った時、あまりがある場合は割った答え+1がチョコを食べた数です。

③もし入力例1の3人目の人

元記事を表示

OTHERカテゴリの最新記事