gabakugik
@gabakugik (GABAKU GIK)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Editがうまくできない

できるようになりました。

def update
    @book = Book.find(params[:id])
    if @book.update(book_params)
      render json: @book
    else
      render json: @book.errors, status: :unprocessable_entity
    end
  end

でいけました。

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

editができない。
axios.putがうまくできない
本の情報を変更ボタンが作動しない
下記のようなエラーがでる。

app/controllers/api/books_controller.rb:26:in `update'
backend_1   | Unpermitted parameter: :id. Context: { controller: Api::BooksController, action: update, request: #<ActionDispatch::Request:0x00007fa97bb01b80>, params: {"book"=>{"id"=>4, "title"=>"Everything is Illuminated", "author"=>"Jerold Prosacco", "publisher"=>"Fairview Press", "genre"=>"Essay"}, "controller"=>"api/books", "action"=>"update", "id"=>"4"}
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.3ms | Allocations: 3066)

コード

vue router

import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'

export default createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: Home,
    },
    {
      path: '/create',
      component: () => import('@/views/Create.vue'),
    },
    {
      path: '/edit/:id',
      component: () => import('@/views/BookEdit.vue'),
    },
  ],
})
Home.vue
<template>
  <div class="container">
    <h1 class="#f3e5f5 purple lighten-5 center">[Rails+Vue.js]~Bookshelf~</h1>
    <div class="row #e3f2fd blue lighten-5">
      <div class="col s4 m6" v-for="book in books" :key="book.id">
        <div class="card btn">
          <span class="card-title" @click="setBookInfo(book.id)">
            {{ book.title }}
          </span>
        </div>
      </div>
    </div>
    <div class="row" v-show="bookInfoBool">
      <div class="col s12 m12">
        <div class="card blue-grey darken-1">
          <div class="card-content white-text">
            <span class="card-title">{{ bookInfo.title }}</span>
            <div class="detail">
              ・著者:{{ bookInfo.author }}
            </div>
            <div class="detail">
              ・出版社:{{ bookInfo.publisher }}
            </div>
            <div class="detail">
              ・ジャンル:{{ bookInfo.genre }}
            </div>
<router-link :to="{ path: `/edit/${bookInfo.id}` }" class="btn">本の編集</router-link>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import axios from 'axios';

const bookInfo = ref({});
const bookInfoBool = ref(false);
const books = ref([]);

const fetchBooks = () => {
  axios.get('http://localhost:3000/api/books').then(
    (res) => {
      books.value = res.data;
    },
    (error) => {
      console.log(error);
    }
  );
};

const setBookInfo = (id: number) => {
  axios.get(`http://localhost:3000/api/books/${id}.json`).then((res) => {
    bookInfo.value = res.data;
    bookInfoBool.value = true;
  });
};

onMounted(fetchBooks);
</script>

<style scoped></style>

BookEdit.vue
<template>
  <div class="container">
    <h1 class="f3e5f5 purple lighten-5 center">本の編集</h1>
    <form class="col s12">
      <div class="row">
        <div class="input-field">
          <input placeholder="Title" type="text" class="validate" v-model="book.title" required />
        </div>
      </div>
      <div class="row">
        <div class="input-field">
          <input placeholder="Author" type="text" class="validate" v-model="book.author" required />
        </div>
      </div>
      <div class="row">
        <div class="input-field">
          <input placeholder="Publisher" type="text" class="validate" v-model="book.publisher" required />
        </div>
      </div>
      <div class="row">
        <div class="input-field">
          <input placeholder="Genre" type="text" class="validate" v-model="book.genre" required />
        </div>
      </div>
      <div class="btn" @click="updateBook(book.id)">本の情報を変更</div>
    </form>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import axios from 'axios';

interface Book {
  id: string;
  title: string;
  author: string;
  publisher: string;
  genre: string;
}

export default defineComponent({
  name: 'BookEdit',
  data() {
    return {
      id: this.$route.params.id,
      book: {
        id: '',
        title: '',
        author: '',
        publisher: '',
        genre: '',
      } as Book,
    };
  },
  mounted() {
    this.setBookEdit(this.id);
  },
  methods: {
    async setBookEdit(id: string) {
      try {
        const response = await axios.get<Book>(`http://localhost:3000/api/books/${id}.json`);
        const data = response.data;
        this.book.id = data.id;
        this.book.title = data.title;
        this.book.author = data.author;
        this.book.publisher = data.publisher;
        this.book.genre = data.genre;
      } catch (error) {
        console.error(error);
      }
    },
    async updateBook(id: string) {
      if (!this.book.title) return;
      try {
        await axios.put(`http://localhost:3000/api/books/${id}`, { book: this.book });
        this.$router.push({ path: '/' });
      } catch (error) {
        console.error(error);
      }
    },
  },
});
</script>

<style scoped></style>
app/controllers/api/books_controller.rb

class Api::BooksController < ApplicationController

  def index
    books = Book.all

    render json: books

    # render json: {book: books}
  end

  def show
    book = Book.find(params[:id])
    render json: book
  end

  def create
    @book = Book.new(book_params)
    if @book.save
      head :no_content
    else
      render json: @book.errors, status: :unprocessable_entity
    end
  end

  def update
    @book = Book.find(params[:id])
    if @book.update(book_params)
      render json: @book
    else
      render json: @book.errors, status: :unprocessable_entity
    end
  end



  def book_params
    params.fetch(:book, {}).permit(
      :title, :author, :publisher, :genre
    )
  end
end

後この情報くださいとかあれば出します。
教えてください。よろしくお願いします。

0

No Answers yet.

Your answer might help someone💌