39
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ベーシックAdvent Calendar 2016

Day 15

今日からできるruby on railsリファクタリングtips12選

Last updated at Posted at 2016-12-15

俺たちに明日はない。

迷い込んだ草木鬱蒼と生い茂る森。
草木を掻き分け進むのに疲れ、倒れこんだ。
ふと香る懐かしい匂い。
彼は思い出した。
そうそれは彼自身が作った森だったのだ。

明日やろうで溜まっていく負債を一つから摘むための
もうほんと今日にでもできるtips集めました。

ベーシックのAdvent Calendar 2016の15日目の記事いきます。

tipsたち

###①後置if
これを!

if ningen=="damono"
     p "mitsuo"
end

こう!

p "mitsuo" if ningen=="damono"

これぐらいのコードなら気にならないですが、
ネストが深くなった場合は分岐をワンライナーにすることを意識。
すっきりします。すっきりは正義。

###②ブロックで後置if
これを!

if type=="mitsuo"
	ningens.each do |damono|
	     p "damono"
	end
end

こう!

ningens.each do |damono|
     p "damono"
end if type=="mitsuo"

ブロック一つから、ネストを防ぎましょう。

###③tryと&.めちゃ便利
kuni.ken.shi.machiのようにできる関連付けられるモデルがあるとき、
kennilkuni.ken.shiをしようとするとnil.shiになり、エラーになります。そこでnilかどうかチェックしますが、

そこで、こういう後置ifを・・・

p kuni.ken.shi if kuni.ken.present?

tryへ!

kuni.ken.try(:shi)

こういうのも・・・

if kuni.present?
	if kuni.ken.present?
		if kuni.ken.shi.present?
			p kuni.ken.shi.machi 
		end
	end
end

こうできる!

kuni&.ken&.shi&.machi

ネストもif文も極力ないのが優しいコードです。
&.を使ってネストやif分岐とさよならしましょう。

###④むしろnil.〜の場合にならないようにする。

例えば、oem.client.idではなくoem.client_idにする。
関連付けられたモデルならシンプルにidを引っ張るようにする。原点回帰!

###⑤transaction
transaction、saveが2個以上あったときに使いました。
sakanactionみたいでかっこいいですし、
ちゃんとロールバックしてくれてデータに誤りが生まれないようにもできます。
saveの間に更新するもので失敗がありえないとしても、
見えづらい制約を作らないためにtransactionしましょう。

###⑥ネストしすぎならreturn if 〜

これを

if ningen=="damono"
     return "mitsuo"
else
     return "dazai"
end

こう!

return "mitsuo" if ningen=="damono"
return "dazai"

###⑦returnでredirect_toとかrenderかぶり回避。

これを

if ningen=="damono"
     redirect_to "mitsuo"
     return
else
if ningen=="shikkaku"
     redirect_to "dazai"
     return
end
redirect_to "murata"

こう!

return redirect_to "mitsuo" if ningen=="damono"
return redirect_to "dazai" if ningen=="shikkaku"
return redirect_to "murata"

###⑧joinsでドゥン
これでchildの中身を見てparentを選べます

parent = Parent.joins(:child).where(childs: {id: child_ids})

###⑨変更は基本、その値のモデルで。
値の変更に条件分岐など必要な場合は、
その対象モデルの中でメソッドを作ってあげてそれを呼ぶんで変更するようにしましょう。
モデルが関連付けが多かったらcontrollerがもっさりするので、modelにわけることでcontrollerをすっきりできます。

###⑩三項演算子で代入
これは、

ningen = 'damono'
ningen = 'shikkaku' if who == "dazai"

こう。

ningen = who == "dazai" ? "shikkaku" : "damono"

###⑪decorator
decoratorはmodelに紐づく形でメソッドを定義できます。
Hitoモデルにmyouzi・namaeがあるとすると
hito_decoratorにfullnameメソッドを用意してhito.decorate.fullname => myouzi + namaeと表示できるように定義します。
viewの記述を減らすためのhelperと考えていいです。
基本的にはdecoratorで値などの実際に変更したりなどしないようにしましょう。とりあえず僕は今までdecoratorで値を変更したことはないです。
はじめhelperとdecoratorがごちゃごちゃしないか不安で無駄なような気がしたのですが、やってみると便利でした。

###⑫共通化しすぎない。
直近関わったプロジェクトが、アカウントとなるモデルが3つありました。
adminとclientとsupplierのように3つあり、モデルそれぞれに違うページを用意する、というようなものでした。
はじめのrailsのイメージでは、adminとclientとsupplierのそれぞれのページは裏では同じソースファイルを参考してたほうがDRYで便利なはずだ!と思っていました。
が、全然違いました。
結局共通化しなくて胸をなでおろしているのですが、共通化してしまうとadminを変更しただけでclientとsupplierの動作チェックも必要になってしまうことになります。これはだるい。
自分は入出力が同じ場合(変数の値による違いしかない場合)のみ共通化しています。

あなたとリファクタリングが手を取り合った未来

目の前の靄がかった景色が晴れ、
いつかのあなたに定時というプレゼントを。

ありがとうございました。

39
26
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?