Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

RailsでFormオブジェクトを使用した場合の、複数テーブルの編集・更新機能の実装方法について

解決したいこと

form objectを使用した際の複数テーブルの編集・更新機能について教えていただきたいです。

Ruby on Railsで本の感想の共有ができるWebアプリをつくっています。
ユーザーが投稿した内容をform objectを使用して複数のテーブルに保存しています。
編集・更新の際に、複数テーブルに保存した内容を1つのビューファイルに表示させる方法、更新する際に改めてform objectを使用して更新・保存を行いたいと考えております。
解決方法を教えていただけたらと思いますので、よろしくお願いいたします。

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

NoMethodError in BooksController#edit
undefined method `find' for BookAuthorObject:Class
Extracted source (around line #47):

  def set_book
    @book = BookAuthorObject.find(params[:id])

  end
end

または、問題・エラーが起きている画像をここにドラッグアンドドロップ。

該当するソースコード

edit.html.erb
  <div class="book-main">
    <h2 class="book-post-content">-書籍の変更内容を入力してください-</h2>
    <%= form_with( model: @book, local: true) do |f| %>
  <%= render 'shared/error_messages', model: f.object %>


    <div class="img-upload">
      <div class="weight-bold-text">
        書籍イメージ
        <span class="indispensable">必須</span>
      </div>
      <div class="click-upload">
        <p>
          クリックしてファイルをアップロード
        </p>
        <%= f.file_field :image, id:"book-image" %>
      </div>
    </div>

    <div class="new-book">
      <div class="book-title">
        <div class="weight-bold-text">
          書籍名
        <span class="indispensable">必須</span>
        </div>
      </div>
      <%= f.text_area :title, class: "title",id:"title", placeholder:"書籍名", maxlength:"40" %>
      <div class="book-author">
        <div class="weight-bold-text">
          著者
          <span class="indispensable">必須</span>
        </div>
      </div>
        <%= f.text_area :name, class:"author", id:"author", placeholder:"著者名を入力してください" , maxlength:"30" %>

      <div class='book-story'>
        <div class="weight-bold-text">
          書籍のあらすじを入力
          <span class="indispensable">必須</span>
        </div>

コントローラー

books_controller.rb
class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update]

<省略>
  def edit
  end

  def update
    @book =  BookAuthorObject.new.update(book_author_object_params)
    if @book.valid?
      @book.update
      redirect_to book_path(@book.id)
    else
      render :edit
    end

  end

  private

  def book_author_object_params
    params.require(:book_author_object).permit(:title, :story, :review, :genre_id, :image, :name).merge(user_id: current_user.id)
  end


  def set_book
    @book = BookAuthorObject.find(params[:id])

  end
end

Form Object

book_author_object.rb
class BookAuthorObject
  include ActiveModel::Model

  attr_accessor :title, :story, :review, :genre_id, :user_id, :image, :name

  with_options presence: true do
    validates :title
    validates :story
    validates :review
    validates :genre_id, numericality: { other_than: 1 }
    validates :name
    validates :image
  end

  def save
    book = Book.create(title: title, story: story, review: review, genre_id: genre_id, image: image, user_id: user_id)
    author = Author.where(name: name).first_or_initialize
    author.save

    BookAuthor.create(book_id: book.id, author_id: author.id)
  end

  def update
    book = Book.update(title: title, story: story, review: review, genre_id: genre_id, image: image, user_id: user_id)
    author = Author.where(name: name).first_or_initialize
    author.save

    BookAuthor.update(book_id: book.id, author_id: author.id)

  end
end


モデル

book.rb
class Book < ApplicationRecord
  belongs_to :user
  has_one_attached :image
  has_many :book_authors
  has_many :authors, through: :book_authors

  extend ActiveHash::Associations::ActiveRecordExtensions

  belongs_to :genre
end

author.rb
class Author < ApplicationRecord
  has_many :book_authors
  has_many :books, through: :book_authors

  validates :name, uniqueness: true
end

book_author.rb
class BookAuthor < ApplicationRecord
  belongs_to :book
  belongs_to :author
end

自分で試したこと

books_controller.rb
  def set_book
    @book = BookAuthorObject.find(params[:id])
  end
#この記述を
  def set_book
    @book = Book.find(params[:id])
  end
#に変更しました。

上記の変更ではBookモデルに保存されているカラムの内容はビューファイルに保存されましたが、Authorモデルに保存されているカラムの内容は表示されませんでした。

次に試したことは、エラーメッセージでメソッドが定義されていませんとありましたので、Form Object内にfindメソッドを定義しましたが変化はありませんでした。

参考にした記事
RailsでFormオブジェクトを使用した場合の、複数テーブルの編集・更新機能の実装方法について

同じような相談がありましたので参考にさせていただいたのですが、edit・update共にうまくいきませんでした。

よろしければ教えていただけたらと思います。

0

No Answers yet.

Your answer might help someone💌