result << object関連のエラーをどうにかしたい(rails)(プログラミング)【三項演算子あり】



このエラーをなんとかしたい状態💦

エラーの深掘り


TypeError in Admin::Articles::PreviewsController#show
→記事プレビュー関連のshowメソッドで受け渡すデータ型に誤りがある??

no implicit conversion of nil into String
→nilをstring型の文字列データに変換しようとした際に問題ありな感じかも

エラー該当箇所

article_blocks.each do |article_block|

# エラーは下の箇所??
# result << xxxでresultに追加してるらしい。今回の処理でいうとif文がtrueやった場合に
# sentence.bodyをresultに代入してる?
result << if article_block.sentence?
sentence = article_block.blockable

# 下の処理でsentenceがnilの場合に問題が起こってるらしい。
sentence.body
elsif article_block.medium?

result << xxxについて

xxxをresultに追加するって意味らしい。
<<は配列に対する追加演算子っぽい。
今回の処理でいうとif文がtrueやった場合にsentence.bodyをresultに追加してる感じかな

じゃあエラーが起こっているのは、文章形のブロックが追加された時にその記入箇所をsentenceに代入したうえで、body部分をresultに追加するけど、そのbodyがnilだった場合にbodyがうまく追加されないから、問題が起こっているという認識なんかな?
if sentence.body?などで条件分岐をするということ?bodyがnilの場合は何も追加せずおわるとか。
該当ファイルがまず見つからん!!!

対象ファイルはapp > controllers > articles > previews_controller.rb?

class Admin::Articles::PreviewsController < ApplicationController
  skip_before_action :require_login

  before_action :preview!

  def show
    @article = Article.find_by!(uuid: params[:article_uuid])
    @article.body = @article.build_body(self)
  end
end

これのbuild_bodyがどっかにあるはず。

あった!!!
app > models > article.rbの部分

    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

完全にこれやわ。

※解決案(間違ってるかも)


sentence.bodyの直前で条件分岐行うとか。

 if sentence && sentence.body # nilかどうかチェック
   sentence.body
 else
    "" 
 # nilの場合は空文字を追加するとかor何も処理しない??

エラー解決した(*´꒳`*)
つまりresultにnil入れると流石に動作しないから、body自体がnilやったらその段階で止めようみたいな感じか( -`ω-)👍🏻

エラー解決したけどlintチェックでメソッド内の処理複雑すぎるからダメって返ってきた。多分条件分岐分けすぎてるから引っかかっちゃった。
下に修正したよん。三項演算子言うらしい。結構使う書き方かもや

三項演算子(かなり使うかも)


result << (sentence && sentence.body ? sentence.body : '')

condition ? true_value : false_valueの形式で条件が真の場合と偽である場合の返す値を1行でまとめて表現できるやつ。

sentence && sentence.body ?が真やったらsentence.body、偽やったら''を返すっていう感じ。

三項演算子の例
普通に条件分岐で書くと

number = 10

if number > 5 
 result = "大きい" 
else 
 result = "小さい"
end

puts result  

↑ってかんじでまあまあ長くなるのを三項演算子使うと

number = 10
result = number > 5 ? "大きい" : "小さい"
puts result  

結構スリムになりますなぁ!!


他にも

array = []
first_element = array.empty? ? "配列は空です" : array.first
puts first_element  # 出力: 配列は空です
number = 7
parity = number.even? ? "偶数" : "奇数"
puts parity  # 出力: 奇数
logged_in = false
message = logged_in ? "ようこそ、ユーザー!" : "ログインしてください。"
puts message  # 出力: ログインしてください。

とかいろいろ汎用性高そう。もともとメソッドに?含まれてる形の場合は?2つ続くからちょっと注意が必要かもやな( -`ω-)👍🏻