rails db:seed
rails db:seedコマンドは、db/seeds.rbの記述に基づいて、データベースにレコードを作成するコマンドです。
クローン直後に投入したい初期データがある場合に利用します。
ターミナル
# 初期データの投入
$ rails db:seed
【例】チケット販売を例とします
users = []
10000.times do |i|
# usersに10000件新規ユーザーの情報を格納する
users << User.new(name: "dummy-#{i+1}", ticket_count: 0)
end
# importメソッドの引数に配列を渡して、まとめてレコードを作成する
User.import users
User.find(500).update(ticket_count: 123456789)
今回は初期データの作成に、activerecord-importというgemを利用しています。
これは、通常通り10000回User.createするよりも、高速に大量のレコードを作成できるからです。
参考リンク
https://qiita.com/xend/items/79184ded56158ea1b97a
例外
例外とは、ある処理を実行した際の結果が、期待されるものと異なる状況を指します。 RubyおよびRuby on Railsでは、Exceptionというクラスを継承する形で様々な例外が定義されています。NoMethodError、SyntaxError などは、全てExceptionクラスの子孫クラスであり、例外です。例外が発生すると、それ以降の処理は中止され、実行されなくなってしまいます。
今回rails db:seedを実行して投入した初期データには、意図的に例外を発生させる値が投入されているものがあります。
# ticket_countをint型で許容できる最大の値にする
User.find(500).update(ticket_count: 123456789)
idが500のユーザーのticket_countを、123456789に変更しています。これは、SQLのinteger型が許容できる最大の値であり、もし123456789より大きな値を保存しようとすると、RangeErrorという例外が発生し、保存に失敗します。ターミナルからrake distribute_ticket:executeを実行してみると、例外の発生するidが500までのユーザーについては、ticeket_countが10増加し、idが500番目以降のユーザーについては、例外が発生してしまったために、処理が中止され、ticket_countが増えていません。
例外処理
例外処理とは、例外が発生した場合に実行する処理のことを指します。Ruby on Railsの開発を行う際に、よく利用するのがrescueです。
上記のrubyプログラムを実行すると、「1 / 0」の処理を行った際に、ZeroDivisionErrorという例外が発生します。これは、数字を0で割ろうとすると発生する例外です。
beginブロックの内部で例外が発生したため、rescue以下の処理が実行されます。
rescue
rescueとは、発生した例外を捕捉し、例外が起こった際に呼び出される条件節です。
例外が発生しそうな部分をbeginから始まるブロックで囲み、ブロックの内部にrescueを記述して使用します。
サンプル
begin
# 数字を0で割ろうとすると、ZeroDivisionError例外が発生する
1 / 0
rescue
# 例外が発生した時にrescue以下の処理が呼ばれる
puts '0で割ることはできません'
end
通常、each, times, whileなどの繰り返しの最中に例外が発生した場合、繰り返し処理は途中で中止され、次のループが実行されることはありません。ただし、繰り返し処理の内部にrescueを記述していた場合、例外が発生したとしても、次のループに移ることができます。
大量のレコードを扱う処理で、例外が発生しても繰り返しを続行したい場合には、rescueを使いましょう。
トランザクション
複数のレコードの更新を1つにまとめて行うことを指します。トランザクションを用いることで、「全て実行されるか、それとも全て実行されないか」という1か0の状況を作ることができます。
サンプル
# ECサイトの購入処理を模した架空のコード
ActiveRecord::Base.transaction do
current_user.pay!(@product.price)
current_user.confirm_purchase!(@product)
end
上記のサンプルは、購入処理を模した架空のコードです。pay!メソッドで商品の料金を払い、confirm_purchase!メソッドで商品の注文を確定させています。料金の支払いと、商品の購入の確定は、常に1つのまとまりとして考えます。トランザクションを用いることによって、「料金の支払いに失敗したけど、商品は購入できた」「料金は支払ったけど、注文の確定に失敗し商品が届かなかった」といった事態を防ぐことができます。
参考リンク
例外と呼んでいたものは、全てこのExceptionクラスを継承しています。
[Ruby Exceptionクラス ドキュメント]
(https://docs.ruby-lang.org/ja/latest/class/Exception.html)
[ActiveRecord Transactions ドキュメント(英語)]
(http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)