学習内容

現状

記事にテキストのコンテンツブロックを挿入した後、テキストを何も入力せずにプレビューページを閲覧するとエラーが発生します。

改修後

上記の操作を行っても、エラーが出ないようにしてください。

記事にテキストのコンテンツブロックを挿入後、テキストを何も入力せずにプレビューページを閲覧すると、以下のエラーが発生する

TypeError - no implicit conversion of nil into String:
訳 nilからStringへの暗黙の変換がない

TypeErrorとは メソッドの引数に期待される型ではないオブジェクトや、期待される振る舞いを持たないオブジェクトが渡された時に発生します。

article.rb

def build_body(controller)
    result = ''

    article_blocks.each do |article_block|
      result << if article_block.sentence?
                  sentence = article_block.blockable
                  sentence.body ||= ''#今回はここを変える!
                elsif article_block.medium?
                  medium = ActiveDecorator::Decorator.instance.decorate(article_block.blockable)
                  controller.render_to_string("shared/_media_#{medium.media_type}", locals: { medium: medium }, layout: false)
                elsif article_block.embed?
                  embed = ActiveDecorator::Decorator.instance.decorate(article_block.blockable)
                  controller.render_to_string("shared/_embed_#{embed.embed_type}", locals: { embed: embed }, layout: false)
                end
    end

    result
  end

元々、sentence.bodyだけだとnill型なので sentence.body ||= ''のようにする。

||= は何をしているか

||=は自己代入やnilガードと呼ばれるそうです。 左辺がnilまたはfalseの場合は右辺が代入され、それ以外の場合は代入はされません。 sentence.bodyに「テスト」と入力して確認してみます。 入力されているのでnilにはならないはずです。

binding.pryをしてnil?メソッド(sentence.body.nill?で確認する)でfalseが返ってきたのでsentence.bodyはnilではないことがわかります。 nilではないので右辺の''(空の文字列)は代入されず「テスト」となっていることがわかる。

Rspec

・FactoryBotで作成するarticleのtitleやslugはsequenceを使ってcreate_listなどで複数件生成してもエラーにならないようにすること

RSpecではcurrent_pathの確認だけではなく表示される要素も確認すること

spec/factories/articles.rb

FactoryBot.define do
  factory :article do
    sequence(:title) { |n| "title-#{n}" }
    sequence(:slug) { |n| "slug-#{n}" }
  end
end