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つ続くからちょっと注意が必要かもやな( -`ω-)👍🏻