新米パパの育児留学

新米パパの育児留学

未経験からエンジニアへの転職体験談など "リアル" な情報を発信

30代未経験からIT・Webエンジニアに転職した私のロードマップ
30代未経験からIT / Webエンジニアへのリアルな転職体験談1 ”エンジニアを目指し求人応募へ”
クロスバイク  LIG(リグ) MOVE 700Cの組み立て手順まとめ
本当に使えるものだけ!出産準備品・ベビー用品で実際に買ってよかったおすすめ10選
Ruby初心者におすすめの学習方法「プロを目指す人のためのRuby入門」
Ruby on Rails チュートリアル 完全攻略 概要と演習解答総まとめ

Rails5.0の主な変更点まとめ

先日Rails5.0(Ruby2.3,Ruby2.4)の新機能勉強会を開催したのでその際の資料をアップします。

本記事は、Rails5.0 の主な新機能についてです。

発表スライド

IT・WEB・ソーシャルゲーム業界への転職ならGEEKLY

Rails 5.0の主な新機能

1. 【重要!】belongs_toのrequiredがデフォルトでtrueに

  • required: true ⇒nilを許容しない(Rails5.0のデフォルト)
  • required: falsenilを許容する (Rails4.xのデフォルト)
  • 親テーブルのレコードがない状態で子テーブルのcreateは失敗する!
  • 親テーブルのレコードがない状態で子テーブルのcreateを成功させるためにはoptional: trueをつける必要がある(Rails4以前と同じ挙動)

DemoA:親テーブル
DemoB:子テーブル

親テーブルのレコードがない状態で子テーブルのcreateは失敗する!

class DemoA < ActiveRecord::Base

end
class DemoB < ActiveRecord::Base
  belongs_to :demo_a #optional 未指定
end
DemoA.inspect #=> “DemoA(id: integer, name: string)“
DemoB.inspect #=> “DemoB(id: integer, demo_a_id: integer)“
DemoB.create.inspect
 (0.2ms) BEGIN
 (0.2ms) ROLLBACK
#=> "#<DemoB id: nil, demo_a_id: 0>"

親テーブルのレコードがない状態で子テーブルのcreateを成功させるためにはoptional: trueをつける必要がある

class DemoA < ActiveRecord::Base

end
class DemoB < ActiveRecord::Base
  belongs_to :demo_a, optional: true
end
DemoA.inspect #=> “DemoA(id: integer, name: string)“
DemoB.inspect #=> “DemoB(id: integer, demo_a_id: integer)“
DemoB.create.inspect
 (0.2ms) BEGIN
 SQL (0.5ms) INSERT INTO `demo_bs` VALUES ()
 (0.2ms) ROLLBACK
#=> "#<DemoB id: 1, demo_a_id: 0>"

2. 【重要!】ActionController::ParametersがHashを継承しない

  • Hashにしかないメソッドは使えない

Rails4

ActionController::Parametersの親クラスの親クラスがHash

# ActionController::Parameters
class Parameters < ActiveSupport::HashWithIndifferentAccess
# ActiveSupport::HashWithIndifferentAccess
class HashWithIndifferentAccess < Hash

Rails5

ActionController::Parametersは何も継承しない

# ActionController::Parameters
class Parameters

3. rakeタスクをrailsコマンドから実行できるように

  • rakeコマンドで実行する各種タスクがrailsコマンドでも実行できるようになった。
  • rakeコマンドも引き続き使用可能だが、railsコマンドを推奨
  • 内部的にrake呼んでいる

sample)

Rails4まで Rails5
rake db:migrate rails db:migrate
rake routes rails routes

4. クエリ関連のメソッド追加(#or, #left_outer_joins, #left_joins)

  • ActiveRecord::RelationにSQLでOR条件を指定できる#orや外部結合を行う#left_outer_joinsのメソッドが追加された
User.where(id:1).or(User.where(id:2))
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE ((id = 1) OR (id = 2))
#=> #<ActiveRecord::Relation [#<User id: 1,・・・>, #<User id: 2,・・・>]>
Author.left_outer_joins(:books)
  Author Load (0.3ms)  SELECT "authors".* FROM "authors" LEFT OUTER JOIN "books" ON "books"."author_id" = "authors"."id"
#=> #<ActiveRecord::Relation [#<Author id: 1, name: "Mark", created_at: "2016-07-20 07:26:57", updated_at: "2016-07-20 07:26:57">, #<Author id: 1, name: "Mark", created_at: "2016-07-20 07:26:57", updated_at: "2016-07-20 07:26:57">]>

5. Enumerableモジュールに#pluckと#withoutが追加

  • RailsでRubyの拡張
  • 特定のレコードのカラムを配列にする#pluckメソッドと似た挙動のメソッドがハッシュの配列でも使えるようになった
  • 配列の中から特定の要素を除く#withoutメソッドが追加された
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
#=> ["David", "Rafael", "Aaron"]
people = ["David", "Rafael", "Aaron", "Todd"]
people.without "Aaron", "Todd"
#=> ["David", "Rafael"]

6. ActiveRecord::Relation#in_batchesメソッドが追加

  • find_in_batchesではブロックの引数がArrayだったが、in_batchesではブロックの引数がActiveRecord::RelationとなるためActiveRecord::Relationのメソッドがつかえる
User.in_batches.class #=> ActiveRecord::Batches::BatchEnumerator
User.in_batches.update_all(verified: true)
User.in_batches.each do |relation|
  relation.class #=> User::ActiveRecord_Relation
  relation.update_all(verified: true)
  sleep 10
end

7. ◯◯::Base の継承が変更

  • モデルの継承元がActiveRecord::BaseからApplicationRecordに変更
  • コントローラがActionController::BaseではなくApplicationControllerを継承しているのと同様
  • ActiveJobActionMailerも同様に変更
  • rails newrails generateで作成されたものが対象であり、既存コードはRails4.2の継承関係のまま

f:id:mochikichi321:20180529184400p:plain

参考:Rails5で起きうるSQL injection

  • Railsのメソッドを使用する際にそのまま使用すると、様々なSQLインジェクションのリスクがある
  • 適切にエスケープなどで対処が必要

Rails SQL Injection

勉強会では紹介しなかった新機能

8. Rails API

  • JSON APIサーバー用の軽量なRailsアプリケーションを構築可能に
  • ActionController::Baseの代わりにActionController::APIをコントローラで継承する
  • ジェネレータでの、ビューやアセットの生成が行われない
  • 完全にAPIのみのRailsアプリケーションを作成する場合は、rails new--apiオプションを指定

$ rails new my_api --api

IT・WEB・ソーシャルゲーム業界への転職ならGEEKLY

参考情報

公式情報

参考ブログ

所感

belongs_toのデフォルト挙動変更は注意が必要。"rakeタスクをrailsコマンドから実行できるように"や"ActiveRecord::Relation#in_batchesメソッド追加"は嬉しい変更だな。

あわせて読みたい記事

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com