Help us understand the problem. What is going on with this article?

Ruby on Railsの現場でよく見る書き方【実例あり】

はじめに

こんにちは、@ryokky59と申します!
未経験からエンジニアになって1年経ちました!
今回はRailsを実務で1年間触ってきて、この書き方は最初に知っておけばスムーズにソースコードが読めたなぁと感じたことをまとめてみました!

この記事で実務と独学の壁がすこしでも埋められるお手伝いができたらいいなと思います!

対象読者

  • 未経験からエンジニアを目指してRailsを勉強している方
  • 普段は他言語を使っているけど今度はRailsを使う現場に行かれる方
  • 自社以外のRailsの書き方を知ってみたい方

Railsのいろんな書き方

埋め込みRuby

文字列の中にRubyの式や変数を埋め込める

user_name = "taro"
"こんにちは#{user_name}さん。今日は#{Date.today}です"
# => "こんにちはtaroさん。今日は2019-12-14です"

""(ダブルクォーテーション)じゃないとRubyが展開されないので注意です。

||=

変数に値を入れるときに、変数がnilかfalseのときのみ値を入れることができます

user1 = "taro"
user1 ||= "jiro"
user1 
# => "taro" ("jiro"が代入されていない)

user2 = nil
user2 ||= "jiro"
user2
# => "jiro" ("jiro"が代入されている)

後置if

例えば以下のようなfalse側がいらないif文がある時

if true
  "trueでhoge"
end
# => "trueでhoge"

こういう時は以下のように一行で書くことができます

"trueでhoge" if true # => "trueでhoge"

例を挙げるとメソッドから抜ける時によく使われます(ガード節といいます。詳しくはコチラ)

def puts_user_name(user_id)
  user = User.find_by(id: user_id)
  return if user.nil? # もしuserがnilだったらreturnでメソッドから抜ける

  puts user.name
end

三項演算子

例えば以下のような普通のif文があるとき、

if true
  puts("trueでhoge")
else
  puts("falseでhuga")
end
# trueでhoge

このような if~else~end で終わるようなif文であれば一行で以下のように書くことができます

true ? puts("trueでhoge") : puts("falseでhuga") # trueでhoge

メソッドの引数その1

メソッドの引数の書き方は ()でも(半角スペース)でも大丈夫です。

User.find(1) # => {id: 1, name: "idが1のユーザー"} 

User.find 1  # => {id: 1, name: "idが1のユーザー"} 

使い分けとしては例えば、上の三項演算子の例ではputs "trueでhoge"みたいに()ではなく、(半角スペース)で書くとSyntaxError unexpected ':' がでてしまいます。
三項演算子は(半角スペース)で次にどの文字がきて欲しいかを予測します。
なのでputs "trueでhoge" と書いてしまうとputsの次が(半角スペース)で:が来ることを期待しているのに"trueでhoge" が来ているのでエラーになります。

このように、()で囲って一つの文として評価されたいか、(半角スペース)で繋げて読みやすくするかを使い分けることができます。

メソッドの引数その2

メソッドに渡す引数の種類もいくつか種類があります。

デフォルト引数

引数にデフォルト値を入れておいて、その引数がなければデフォルト値を使います

def puts_string(string="文字列")
  puts string
end

puts_string # "文字列"

キーワード引数

引数をハッシュで指定する。
実行するときにキーワードも指定する必要がある。
引数が複数だったり、明示的にしたいときに使われる。

def puts_string(string:)
  puts string
end

puts_string(string: "文字列") # "文字列"

可変長引数

引数を配列として受け取ることができる

def name_array(*name)
  p name
end

puts_name_array("taro", "jiro", "saburo")
# => ["taro", "jiro", "saburo"]

!◯◯(変数)

変数の前に!を書くと中身を反転したbooleanの形(trueまたはfalse)に変換することができます

下記のようにstringという変数の前に一つ!をつけると反転してfalse、さらにもう一つ!をつけるとさらに反転してtrueを返します。

string = "文字列"
string   # => "文字列"
!string  # => false
!!string # => true

変数の中身をnilにすると理解しやすいかもしれません

nil_val = nil
nil_val   # => nil
!nil_val  # => true
!!nil_val # => false

%記法

配列はよく%記法を用いて書かれます。

%w(hoge huga foo bar) # => ["hoge", "huga", "foo", "bar"]

注意するところは配列の中身は必ずstringになるというところです

%w(1 2 3) # => ["1", "2", "3"]

シンボルにすることもできます

%i(new create delete) # => [:new, :create, :delete]

{}

ブロックは do~end で書くことが多いかもしれませんが {} を使って一行で書く時に読みやすくすることができます。

%w(hoge huga foo).each do |string|
  puts string
end
%w(hoge huga foo).each{ |string| puts string }

この二つはどちらも同じ結果を返します。
do{ に、 end} に置き換わっただけですね
ブロックの中身が短く単純な時に便利です。

[1, 2, 3, 4].select { |item| item % 2 == 0 } # => [2, 4]

上のように selectany? など配列、ハッシュを扱うメソッドを使う時によく見られます

map(&:〇〇)

こちらは先ほどの{}で囲むブロック分よりさらに短縮したような書き方です。

users.map { |user| user.name } # => ["taro", "jiro", "saburo"]

users.map(&:name) # => ["taro", "jiro", "saburo"]

上の例ではオブジェクトのキーを指定して値を取り出しています
これはブロックをprocに変換しているからできます。
実際はmapメソッドだけでなく他の配列、ハッシュを扱うメソッドで使うことができます。

procとかは聞き慣れないかなと思うので参考記事を置いておきます
Rubyのmap &:to_iとはなんなのか
Ruby Procについて学ぶ

items.sort_by(&:created_at) # itemのcreated_atが古い順に並び替える

includes

引数に書いたモデルを先読みしてキャッシュしておく。
簡単にいうと不要なSQLを発行しないようにしてパフォーマンス低下を防ぐ(N+1問題を防ぐ)

@user = User.all.includes(:items)

↑のようにしておくと@user.itemsをeachで回したときにitem.nameとかでitemの数だけSQLが発行されるのを防ぐ
詳しくは下記記事を参考にどうぞ
Rails で includes して N+1 問題対策

&.(セーフナビゲーション)

別名ぼっち演算子
エラーの代わりにnilを返してくれます。

# userのnameがnilのとき

user.name.length # => NoMethodError: undefined method `length' for nil:NilClass

user.name&.length # => nil

nilの値であるレシーバ(name)に対してlengthメソッドを実行するとエラーが出ますが、&.でチェーンすることでnilに変わります。
nilが入る可能性のあるカラムを操作するときによく使われます。

each_with_index

eachで回すときにindexが欲しいときに使います。

users = %w(taro jiro saburo)

users.each_with_index do |user, index|
  puts "user: #{user}, index: #{index}"
end

# user: taro, index: 0
# user: jiro, index: 1
# user: saburo, index: 2

indexを任意の数字で始めることもできます

users = %w(taro jiro saburo)

# eachにチェーンしてwith_indexを繋げていることに注意
users.each.with_index(1) do |user, index|
  puts "user: #{user}, index: #{index}"
end

# user: taro, index: 1
# user: jiro, index: 2
# user: saburo, index: 3

おわりに

現場では他にも色々書き方はあると思いますが、ここまでの内容を抑えておけばそこそこスムーズにソースコードを読めるのではないでしょうか?
他にも「うちではこんな書き方あるよ!」みたいな方はお気軽にコメントください!

他記事への参考リンク

これからRailsを触っていく方に役に立つなと感じたリンクです。
(一部この記事を書く際にも参考にさせていただきました。m(_ _)m)
他言語経験者がRailsの案件にジョインしたときに、何を足掛かりにすべきか
差をつけるRuby

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした