
Completed 500 Internal Server Error in 83ms (ActiveRecord: 3.7ms)
TypeError - no implicit conversion of nil into String:
app/models/article.rb:79:in `block in build_body'
app/models/article.rb:70:in `build_body'
app/controllers/admin/articles/previews_controller.rb:8:in `show'
直訳すると「nilからStringへの暗黙の変換がない」という意味のエラーです。
sentence.body
の中身がnil
である事からエラーになっていることが推測されます。
result << if article_block.sentence?
sentence = article_block.blockable
sentence.body
nilガードを使用
今回はnil
を防ぐ為のテクニックとして、nil
ガードを使いたいと思います。
result << if article_block.sentence?
sentence = article_block.blockable
sentence.body ||= ''
コードを紐解く
sentence.body ||= ''
上記コードはつまり、sentence.body
があればsentence.body
を返し、無ければ''
を代入する。といった意味です。
nilガードは、変数にnilが入っているかもしれない状況で、nilの代わりに何らかのデフォルト値を入れておきたいという場面で便利なメソッドです。
これでsentence.body
の中身がnil
である場合も、安心して中身が必ず入っている前提のコードを書くことができます。
67: def build_body(controller)
68: result = ''
69:
70: article_blocks.each do |article_block|
71: result << if article_block.sentence?
72: sentence = article_block.blockable
73: binding.pry
=> 74: sentence.body ||= ''
75: elsif article_block.medium?
76: medium = ActiveDecorator::Decorator.instance.decorate(article_block.blockable)
77: controller.render_to_string("shared/_media_#{medium.media_type}", locals: { medium: medium }, layout: false)
78: elsif article_block.embed?
79: embed = ActiveDecorator::Decorator.instance.decorate(article_block.blockable)
80: controller.render_to_string("shared/_embed_#{embed.embed_type}", locals: { embed: embed }, layout: false)
81: end
82: end
83:
84: result
85: end
[1] pry(#<Article>)> sentence
=> #<Sentence:0x0000000117da6ae8
id: 3,
body: nil,
created_at: Thu, 04 Nov 2021 15:13:08 JST +09:00,
updated_at: Thu, 04 Nov 2021 15:13:08 JST +09:00>
[2] pry(#<Article>)> sentence.body
=> nil
[3] pry(#<Article>)> sentence.body ||=''
=> ""
コメント