Rails RecordNotFound не может найти альбом с идентификатором - PullRequest
0 голосов
/ 18 апреля 2020

Я в конце приложения Rails с вложенными ресурсами, но не могу понять, как удалить рецензию. Я могу удалить альбом просто отлично. Мои обзоры принадлежат альбомам. У пользователей есть как альбомы, так и обзоры.

Я также хотел бы убедиться, что пользователи не могут удалять отзывы, которые они не написали. Я думаю, что отсюда моя ошибка.

Я получаю эту ошибку:

ActiveRecord::RecordNotFound in AlbumsController#destroy
Couldn't find Album with 'id'=17
Extracted source (around line #57):
55
56
57
58
59
60


    def set_album
        @album = Album.find(params[:id])
    end

    def album_params

Вот мой контроллер отзывов:

class ReviewsController < ApplicationController
    before_action :set_review, only: [:show, :delete, :edit, :update]
    before_action :set_current_user, only: [:index, :new, :edit, :delete]
    before_action :find_album, only: [:create, :edit]
    before_action :must_login, only: [:index, :new, :create, :edit, :update, :delete]

    def index
        @albums = Album.with_recent_reviews
    end

    def show
        #@reviews = Review.where("album_id = ?", params[:album_id])
    end

    def new
        if params[:album_id] && @album = Album.find_by(id: params[:client_id])
            @review = @album.reviews.build
        else
            redirect_to albums_path
        end
    end

    def create
        @review = current_user.reviews.build(review_params)
        @review.album = @album
        if @review.save
            redirect_to album_path(@album)
        else
            @album = @review.album
            render :new
        end
    end

    def edit
    end

    def update
        if @review.update(review_params)
            redirect_to album_path(params[:album_id])
        else
            render 'edit'
        end
    end

    def destroy
        if current_user.id == @review.user_id
            @review.destroy
            redirect_to album_path(params[:album_id])
        else
            flash[:error] = "Unable to delete your review. Please try again."
            redirect_to album_reviews_path(@review)
        #@review.destroy
        end
    end

    private

    def set_review
        @review = Review.find(params[:id])
    end

    def set_current_user
        @user = current_user
    end

    def find_album
        @album = Album.find(params[:album_id])
    end

    def review_params
        params.require(:review).permit(:title, :date, :content, :user_id, :album_id, album_attributes:[:artist, :title, :user_id])
    end

end

Вот мой Форма индекса отзывов, где находится ссылка для удаления:

<% @albums.each do |album| %>
  <br>
  <br>
  <% if album.avatar&.attached? %>
    <image src="<%=(url_for(album.avatar))%>%" style="width:350px;height:350px;">
  <% end %>
  <br>
  <%= album.artist %> - <%= album.title %>
  <br>
  <%= link_to "View Album", album_path(album) %>
  <%= link_to "Edit Album", edit_album_path(album) %>
  <br><br>
  <% album.reviews.each do |review| %>
    <% unless review.id.nil? %>
        <small>Date written: <%= review.date %></small><br>
        <small>Written by: <%= review.user.name %></small><br>
        <strong>Title: <%= review.title %></strong><br>
        Review: <%= review.content %><br>
        <%= link_to "Edit Review", edit_album_review_path(album_id: album.id, id: review.id) %>
        <%= link_to 'Delete', album_path(album_id: album.id, id: review.id), method: :delete, data: { confirm: 'Are you sure?' } %>
        <br><br>
    <% end %>
<% end %>
  <br>
<% end %>

Контроллер альбомов:

class AlbumsController < ApplicationController
    before_action :set_album, only: [:show, :edit, :update, :destroy]
    before_action :must_login, only: [:new, :show, :create, :edit, :update, :destroy]

    def index
        @albums = Album.all
        @user = current_user
    end

    def show
        @review = @album.reviews.build
        @review.user = current_user
        # If you want to have some flag to indicate its status
        #@review.draft = true
        @review.save
        @reviews = Review.recent #scope
    end

    def new
        @album = Album.new
        @user = current_user
    end

    def create
        @user = User.find(current_user.id)
        @album = current_user.albums.build(album_params)
        @album.user_id = current_user.id
        if @album.save
            redirect_to album_path(@album)
        else
            render :new
        end
    end

    def edit
        @user = current_user
    end

    def update
        #@album = current_user.albums.build(album_params)
        @album.user_id = current_user.id
        if @album.update(album_params)
            redirect_to album_path(@album), notice: "Your album has been updated."
        else
            render 'edit'
        end
    end

    def destroy
        @album.delete
        redirect_to albums_path
    end

    private

    def set_album
        @album = Album.find(params[:id])
    end

    def album_params
        params.require(:album).permit(:artist, :title, :avatar, :user_id, review_attributes:[:title, :date, :content, :user_id, :album_id])
    end
end

1 Ответ

1 голос
/ 18 апреля 2020

У вас есть эта проблема, потому что вы не передаете параметр album_id в действие уничтожения контроллера просмотра. Причина, по которой вам нужен album_id, заключается в том, что ваши маршруты, вероятно, выглядят следующим образом (поскольку вы сказали, что они были вложенными):

http://localhost:3000/albums/1/reviews

В вашем маршруте вы можете увидеть, что вам нужен album_id (1 после альбома) , Попробуйте изменить действие по уничтожению обзора следующим образом:

def destroy
  if current_user.id == @review.user_id
    @album.reviews.find(params[:id]).destroy
    redirect_to album_path(params[:album_id])
  else
     flash[:error] = "Unable to delete your review. Please try again."
     redirect_to album_reviews_path(@review)
  end
end

Вам также придется изменить свою before_action в контроллере обзора на это, так как для уничтожения обзора вам нужен album_id:

before_action :find_album, only: [:create, :update, :destroy]
...