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