Rubyにおけるif文
ifを使うことで、「XXを満たしたらこの処理、そうでなければこの処理」といったような、条件分岐が実現できる。
num = 5
if num < 0
puts '符号はマイナスです'
else
puts '符号はプラスです'
end
上記を実行すると 符号はプラスです
と出力される、のは置いといて...。
num < 0
ここが条件式に当たる。
条件式にはルールがある。
- 条件式を評価して
nil
またはfalse
が得られたら偽 - それ以外は真
従って以下のような書き方でもOK
num = 5
if num
puts '符号はマイナスです'
else
puts '符号はプラスです'
end
この性質を利用して、Railsでは以下のようなちょっと不思議な書き方ができる。
app/controllers/blogs_controller.rb
@blog = Blog.new(title: 'aaa', content: 'bbb')
if @blog.save
redirect_to @blog
else
render :new
end
if @blog.save
当然注目すべきはココ。
なぜこんな書き方ができるのか
その答えはrailsコンソールで実行すればわかる。
irb(main):001:0> blog = Blog.new(title: 'aaa', content: 'bbb')
=> #<Blog id: nil, title: "aaa", content: "bbb", created_at: nil, updated_at: nil>
irb(main):002:0> blog.save
(0.2ms) begin transaction
SQL (8.4ms) INSERT INTO "blogs" ("title", "content", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "aaa"], ["content", "bbb"], ["created_at", "2017-06-29 16:26:35.819755"], ["updated_at", "2017-06-29 16:26:35.819755"]]
(1.2ms) commit transaction
=> true
saveメソッドを実行したら INSERT INTO "blogs"...
とSQLが実行され、最後に true
という値が返ってきてるのが確認できる。
では今度はモデルにバリデーションを実装して、わざと引っ掛けてみる。
app/models/blog.rb
class Blog < ActiveRecord::Base
validates :title, presence: true
end
先ほどと同じようにrailsコンソールでBlogクラスのインスタンスを生成した後、saveメソッドを実行させる。
irb(main):001:0> blog = Blog.new(content: 'bbb')
=> #<Blog id: nil, title: nil, content: "bbb", created_at: nil, updated_at: nil>
irb(main):002:0> blog.save
(0.2ms) begin transaction
(1.2ms) rollback transaction
=> false
今度は false
が返ってきてるのが確認できる。
この2つから、 @blog.save
も条件式となるための条件は満たしているのだ。
ちなみにsaveに !
をつけるとtrue/falseではなく例外 Title can't be blank
が返るので、こちらも合わせて覚えておきたい。
irb(main):003:0> blog.save!
(0.1ms) begin transaction
(0.1ms) rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Title can't be blank
まとめ
- Rubyのif文において条件式を評価し、戻り値がnilまたはfalseの時は
偽
それ以外は真
となる。 -
if @blog.save
と書けるのは、saveメソッドがINSERT INTO (table_name) .....というSQLの実行だけでなく、保存が成功したらtrue、Validationなどにより失敗したらfalseが戻り値として得られるから。