【脱初心者】RubyとRailsの曖昧なメソッドを理解する
はじめに
近頃冷え込んできましたね、@chiba_dです。
8月から新卒インターンとして参加している私も、業務に関わる中で学びが多い状態を継続できています!
COUNTERWORKSではSHOPCOUNTERというサービスを運営しています。
SHOPCOUNTERではフロントにNext.js、バックエンドにRailsを使用しています。
研修の中でプロダクションのコードに触れて、多くの学びや気づきがありました。
そこでRailsチュートリアル1周レベルの私が、入社後に新しく学んだ・理解したRuby・Railsの記述について備忘録的にまとめます。
記事の内容
この記事では私が初学者の状態から業務に関わる中で、RubyとRuby on Railsの曖昧だと感じて、調べ直した記法を順番に紹介します!
必要に応じて
- 何が違うか(what)
- どう使い分けるか(how)
を記載します。
この記事で勉強して業務レベルのコードを読めるようになりましょう!
対象読者
- Ruby・Railsに詳しくなりたい人
- Railsチュートリアル1周した人
全体
member:(名前付き引数)、:member(シンボル)
項目 | 例 | 内容 |
---|---|---|
キーワード引数 | member: | 引数を渡す際にkeyを指定して渡す |
シンボル | :member | 値を代入するための変更不可能な文字列の変数 |
- what(違い)
:が前と後ろのどちらについているか - how(使い分け)
キーワード引数はkey,シンボルはvalueとして扱う
ハッシュ、配列
項目 | 例 | 内容 |
---|---|---|
ハッシュ (連想配列) | {"name" => "Taro", "internet_name" => "漆黒の太郎"} | keyとvalueが一意に対応するオブジェクト |
配列 | ["Sato", "Yoshida", "Suzuki"] | valueのみを複数持つオブジェクト |
- what(違い)
keyが存在するか - how(使い分け)
レスポンスの設計などkeyが必要な処理ではハッシュ、単純なループ処理では配列
ハッシュではシンボルと文字列の両方をkeyとして定義できます。
valueを読み込む際のkeyの指定には、定義した形式(文字列なら)で記述が必要です。
ハッシュを配列に格納すること、ハッシュにハッシュをvalueとして定義することもできます。
API Routeにおける単数、複数
項目 | 例 | 内容 |
---|---|---|
単数 | PATCH ~/members/1 | update,deleteなどの一つのレコードにのみ作用する場合 |
複数 | POST ~/members | index,createなどの全て・複数のレコードに作用する場合 |
- what(違い)
APIが実行する処理の対象が単数か複数かで記述を変える - how(使い分け)
同上
:: と . と _
項目 | 例 | 内容 |
---|---|---|
:: | Api::V1::User | クラス、定数呼び出しで用いる |
. | User.all | メソッド呼び出しで用いる |
_ | _ | 任意の一文字に該当するワイルドカード,数値の区切りに使える |
- what(違い)
クラス(定数)の呼び出しとメソッドの呼び出し - how(使い分け)
省略
@@と@とdef +@
項目 | 例 | 内容 |
---|---|---|
@@ | @@user | クラス変数 |
@ | @user | インスタンス変数 |
def +@ | def +@, +: taro | 単項演算子を定義する表記 |
- what(違い)
変数のスコープが異なる - how(使い分け)
省略
attr, params
項目 | 例 | 内容 |
---|---|---|
attr | attr_accessor :name | コントローラー内でオブジェクトの属性を定義する |
params | https://~/user/1 , params[:id] | クエリパラメータとして送られてくる値を取得するメソッド |
- what(違い)
attrはオブジェクトの属性を定義する、paramsはURLに含まれる値を取得するメソッド - how(使い分け)
省略
paramsはルーティングにおいても/user/:idのように指定して、どこがparamsであるかを教える必要があります
class, module, helper
項目 | 例 | 内容 |
---|---|---|
class | class User | インスタンスが作れる、メソッドもまとめた概念 |
module | module User | インスタンスが作れない、メソッドのみをまとめた概念 |
helper | module User | ビューファイルで用いることが可能なモジュール |
- what(違い)
インスタンスが作れるかどうか、ビューファイルで用いるかどうかが異なる - how(使い分け)
同上
transaction {}, hash {}
項目 | 例 | 内容 |
---|---|---|
transaction {} | ActiveRecord::Base.transaction do end | トランザクションを記述する、処理途中のエラーが発生したらロールバック |
hash {} | hash do end | ハッシュの各属性を検証するときに使う |
- what(違い)
トランザクションを書くか、ハッシュの検証を書くか - how(使い分け)
同上
include, include?
項目 | 例 | 内容 |
---|---|---|
include | include Greet | モジュールの読み込み |
include? | "Yamada".include?("Yama") | 指定する文字列を含むかどうか |
- what(違い)
クラスとモジュールのどちらを読み込むか - how(使い分け)
同上
&と&.とdef xxx(&aaa)とxxx(&bbb)
項目 | 例 | 内容 |
---|---|---|
論理積 | & | 通常の論理積演算子 |
ボッチ演算子 | &. | インスタンスがnilでなければメソッドを実行し、nilならばnilを返す記述 |
ブロック引数 | def xxx(&aaa) | メソッドを定義する際にブロックを渡すことを記述する |
Procを用いるメソッド呼び出し | xxx(&bbb) | Procオブジェクトをブロックとして渡してメソッドを呼び出す |
- what(違い)
演算子、メソッド定義、メソッド呼び出しが異なる - how(使い分け)
省略
alias,alias_method,scope
項目 | 例 | 内容 |
---|---|---|
alias | alias new_name old_name | グローバル変数に別名を付ける |
alias_method | alias_method :new_method :old_method | インスタンスメソッドに別名を付ける |
scope | scope :current, -> { where(login_current: true) } | 別名で呼び出せるように条件式を定義する |
- what(違い)
対象が変数かインスタンスメソッドか条件式かで異なる - how(使い分け)
同上
->と=>
項目 | 例 | 内容 |
---|---|---|
-> | num = -> (a){a*a} | lambda記法 |
=> | {"name" => "Taro"} | ハッシュのリテラル |
- what(違い)
無名関数の定義かハッシュのkey-value定義か - how(使い分け)
省略
メソッド
find, find_by, find_by!
項目 | 例 | 内容 |
---|---|---|
find | User.find(1) | 該当するidのレコードを取得するメソッド |
find_by | User.find_by(name: "Taro") | 指定した属性・値を持つ初めに見つかったレコードを取得するメソッド、取得できなかった際nilを返す |
find_by! | User.find_by!(name: "Taro") | find_byと同じメソッドだが、取得できなかった際エラーを返す |
- what(違い)
idでレコードを取得するかどうか、取得できなかった際の戻り値で異なる - how(使い分け)
同上
each, find_each
項目 | 例 | 内容 |
---|---|---|
each | [1,2,3].each do | ループ処理で要素を取り出す |
find_each | User.all.find_each do | ループ処理で要素を取り出す、大規模なデータの処理で効率的なSQLを作成する |
- what(違い)
全レコードをメモリに読み込むか、データベースクエリの実行時間 - how(使い分け)
ActiveRecord関連の1000件を超えるようなデータ処理ではfind_eachを用いる方がよい、それ以外ではeachでも問題ない
モデル
.idとids
項目 | 例 | 内容 |
---|---|---|
.id | user.id | オブジェクトのもつidを参照する |
ids | User.ids | 主キーのカラムを取り出す(SQL) |
- what(違い)
オブジェクトのidを参照するか主キーのカラムを取り出すか - how(使い分け)
同上
through, source
項目 | 例 | 内容 |
---|---|---|
through | has_many :users, through: :favorites | 中間モデルを通して関連モデルを参照する |
source | has_many :favorite_posts, through: :favorites, source: :posts | 存在しない関連付けに対して、throughを通して実際に参照する関連モデル |
- what(違い)
throughは中間モデルを記載する、sourceは実際に参照する関連モデルを記載する - how(使い分け)
同時に使うため省略
belongs_to, has_one
項目 | 例 | 内容 |
---|---|---|
belongs_to | belongs_to :favorite | 自らが外部キーとして相手モデルの主キーをカラムとして持つ |
has_one | has_one :user | belongs_toの説明の相手モデル側、外部キーをカラムとして持たない |
- what(違い)
外部キーが定義されたカラムを持つか - how(使い分け)
外部キーをカラムとして持つ側かどうかで変える
テスト関連(RSpec,FactoryBot)
let, let!
項目 | 例 | 内容 |
---|---|---|
let | let(:user) {User.new(name: "Taro", age: "18")} | 遅延評価で値を定義する |
let! | let!(:user) {User.new(name: "Taro", age: "18")} | 即時評価で値を定義する |
- what(違い)
参照されたタイミングで値が決定するかどうか - how(使い分け)
処理の途中で値が変わる可能性がある場合即時評価を使う
create, build
項目 | 例 | 内容 |
---|---|---|
create | FactoryBot.create(:user) | FactoryをDB上に作成する |
build | FactoryBot.build(:user) | Factoryをメモリ上に作成する |
- what(違い)
FactoryをDB上に持つか、メモリ上に持つか - how(使い分け)
ActiveRecordが関連する場合はcreateを使う
subject, describe, context, it
項目 | 例 | 内容 |
---|---|---|
subject | subject { math.sum } | is_expectedで評価される式を定義する |
describe | describe '足し算' do | 実行するテストの大枠を記載する |
context | context '整数の時' | 条件分岐・状況を記載する |
it | it '1+1 = 2であること' do | テストの詳細を記述する |
- what(違い)
記載内容、describe > context > itの順で外側から記載する - how(使い分け)
同上
delete, soft_delete
項目 | 例 | 内容 |
---|---|---|
delete | user.delete | レコードの物理削除を行う |
soft_delete | user.soft_delete | レコードの論理削除を行う |
- what(違い)
レコードを実際に削除するか - how(使い分け)
データを削除後も残しておきたいかどうか
member, collection
項目 | 例 | 内容 |
---|---|---|
member | resources :users do member do get 'account' end end | ルーティングにおいてresource とmemberの間に:idを持つ |
collection | resources :users do collection do get 'account' end end | ルーティングにおいてresource とcollectionの間に:idを持たない |
- what(違い)
idを受け取るかどうか - how(使い分け)
コントローラーでparams[:id]を用いるかどうか
おわりに
いかがだったでしょうか!
この記事では私の経験をもとにRubyとRuby on Railsの初心者が曖昧になりがちな記述について解説しました。
この記事が初学者の手助けになれば幸いです。
今後も学習途中の不明点は理解した後に備忘録として残しておきたいと思います。
We are hiring !!
COUNTERWORKS では一緒に働く仲間を絶賛募集中です。
今後の更なる成長のためには圧倒的に仲間が不足しています。皆さまのご応募お待ちしております!
参考
ポップアップストアや催事イベント向けの商業スペースを簡単に予約できる「SHOPCOUNTER」と商業施設向けリーシングDXシステム「SHOPCOUNTER Enterprise」を運営しています。エンジニア採用強化中ですので、興味ある方はお気軽にご連絡ください! counterworks.co.jp/
Discussion
Railsチュートリアル/Railsガイドについて言及していただきありがとうございます! 😻✨
細かな点で恐縮ですが以下の「単数」の部分については
members/1
になるかなと思いました! ✅参考: CRUD、verb、アクション - Railsガイド
ご参考になれば幸いです...!! 🙏✨
ご指摘頂きとても助かります!ありがとうございます!🙏
指摘事項に関して仰る通り私の誤りでした。
member/1
->members/1
誤った記述でしたので、上記の通り修正いたしました。(2023/12/19)
(RailsガイドとRailsチュートリアルを頻繁に読んでおります!重ねてお礼申し上げます✨)