shunta9922
@shunta9922 (shimo shun)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

no method errorについて

解決したいこと

Ruby on Railsで映画についてつぶやけるWebアプリをつくっています。
投稿詳細で編集し投稿詳細へ戻るフローを実装しているのですが、updateの処理でno method errorが発生します。
image_nameメソッドはshowアクションで呼び出しているのでupdateアクションでは呼び出す必要がないと認知しているのですがここでなぜ呼び出すのか頭を抱えています。

発生している問題・エラー

NoMethodError in Movies#update
undefined method `image_name' for nil:NilClass             
      <div class="movie-show-item">
         <div class="movie-user-name">
           <img src="<%= "/user_images/#{@user.image_name}" %>">
           <%= link_to(@user.name,"/users/#{@user.id}") %>  
         </div> 
         <p>

該当するソースコード

edit.html.erb
<div class="main movie-new">
    <div class="container">
     <h1 class="form-heading">編集する</h1>
        <%= form_with model:@movie,local: true do |f| %>
            <div class="form" >
                <div class="form-body">
                    <% @movie.errors.full_messages.each do |message| %>
                        <div class="form-error">
                            <%= message %>
                        </div>
                    <% end %>
                    <%= f.text_field :title %>
                    <%= f.text_area :content %>
                    <%= f.submit value="保存" %>
                </div>
            </div>
        <% end %>
    </div>
</div>
 def show
   @movie =Movie.find(params[:id])
   @user = User.find(@movie.user_id)
   @likes_count = Like.where(movie_id: @movie.id).count
   @comments = Comment.includes(:user).where(reply_comment: @movie.id)
   @comments = Comment.all
   @comment = Comment.new
  end

  def new
   @movie=Movie.new
  end

  def create
   @movie=Movie.new(
     content: params[:content],
     title: params[:title],
     user_id: @current_user.id
  )
   if @movie.save
     flash[:notice]= "投稿を作成しました"
     redirect_to movies_path(@movie)
     binding.pry
   else
      render("movies/new")
   end

 end

  def edit
   @movie=Movie.find_by(id: params[:id])
  end

  def update
   @movie = Movie.find_by(id: params[:id])
   @movie.content=params[:content]
   @movie.title=params[:title]



   if @movie.save
     redirect_to movie_path(@movie)
     flash[:notice]="変更しました"

   else
     render ("movies/show")
   end
  end

routes
 root 'home#top'
 resources :movies do
   resources :comments 

  collection do
     get 'search'
   end
schema

  create_table "movies", force: :cascade do |t|
    t.text "content"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.string "title"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "image_name"
    t.string "password_digest"
    t.boolean "admin", default: false
  end
0

1Answer

image_nameメソッドはshowアクションで呼び出している

これはやや不正確で、show.html.erbという名前のViewファイル内の以下の場所でNoMethodErrorが発生していると思われます。特に指定しなかった場合にshowメソッドがshow.html.erbを呼び出しているにすぎません。

show.html.erb
  <img src="<%= "/user_images/#{@user.image_name}" %>">

ではどこでこれが起きるかというと、仰る通りMovies#updateの中で、@movie.saveが失敗した際にrender ("movies/show")しているためです。

  def update
   @movie = Movie.find_by(id: params[:id])
   @movie.content=params[:content]
   @movie.title=params[:title]



   if @movie.save
     redirect_to movie_path(@movie)
     flash[:notice]="変更しました"

   else
     render ("movies/show") # <= ここ
   end

失敗した場合編集画面を再表示してエラーメッセージを出したいのかなと推測すると、

render ("movies/edit")

の間違いでしょうね。

なお、お節介だとは思いますが、過去の解決した質問等はクローズするとよいかと思われます...。

2Like

Comments

  1. @shunta9922

    Questioner

    回答ありがとうございます。おっしゃる通りrenderに問題がありました。ご指摘ありがとうございます。

Your answer might help someone💌