中間テーブルが保存されずタグを配列として表示できない
中間テーブルを用いて投稿に紐ずくタグを配列として表示させたい
現在、投稿に紐ずくタグ付け機能を実装しているのですが、タグが配列として複数表示できるような実装
をイメージしております。
配列としてタグを複数投稿できるような実装に変えたところ、今まで保存できていた中間テーブルが保存できないようになり、投稿にタグが表示されずにタグも配列として保存されずにひとかたまりにデーターベースに保存されてしまいます。
また、formオブジェクト
を用いて複数のテーブルに保存される機能にしているため、どのような記述方法が正解なのか分からない状況です。
formオブジェクトやタグ付け機能などの詳しい方がおりましたら、ご教授願えますでしょうか。
発生している問題・エラーメッセージ
1・保存したタグが配列として取得できない
2・投稿テーブルとタグテーブルにおける中間テーブルの値が保存されない
3・投稿時にエラーが表示されるが、データベース常に値は保存されておりトップページに戻ると問題なく表示される
上記1、2のコンソール上の出力結果
[1] pry(#<UploadsController>)> UploadTagRelation.create
=> #<UploadTagRelation:0x00007fdb13f9cdb0 id: nil, upload_id: nil, tag_id: nil, created_at: nil, updated_at: nil>
[2] pry(#<UploadsController>)> params[:upload_form][:name]
=> "東京 渋谷 カフェ"
[3] pry(#<UploadsController>)>
投稿時に表示されるエラー画面
NameError in UploadsController#create
undefined local variable or method `tag' for #<UploadForm:0x00007fdb25ceff38 @errors=#<ActiveModel::Errors:0x00007fdb25ced7b0 @base=#<UploadForm:0x00007fdb25ceff38 ...>, @errors=[]>, @title="カフェ", @text="タグカフェ", @url="", @working_day="", @day_off="", @cafe_wifi_id="1", @cafe_charging_id="1", @cafe_smoking_id="1", @image=#<ActionDispatch::Http::UploadedFile:0x00007fdb13eb42e0 @tempfile=#<Tempfile:/var/folders/gw/k3mqyqh15y37h56g1b17ymvc0000gn/T/RackMultipart20210514-85259-f73ob5.jpeg>, @original_filename="2f211d6f387d6006a68f.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"upload_form[image]\"; filename=\"2f211d6f387d6006a68f.jpeg\"\r\nContent-Type: image/jpeg\r\n">, @name="東京 渋谷 カフェ", @user_id=1, @validation_context=nil>
Did you mean?
tap
Extracted source (around line #32):
30
31
32
33
34
end
UploadTagRelation.create(upload_id: upload.id, tag_id: tag.id)⇦この部分
end
end
tag_list = params[:upload_form][:name].split(",")
if @upload.valid?
@upload.save(tag_list)⇦この部分
redirect_to root_path
else
render new
該当のソースコード
app/controllers/upload_controller
class UploadsController < ApplicationController
def index
@uploads = Upload.all.order(created_at: :desc)
end
def new
@upload = UploadForm.new
end
def create
# binding.pry
@upload = UploadForm.new(upload_params)
tag_list = params[:upload_form][:name].split(",")
if @upload.valid?
@upload.save(tag_list)
redirect_to root_path
else
render new
end
end
def show
@upload = Upload.find(params[:id])
@tag = @upload.tags
end
def destroy
@upload = Upload.find(params[:id])
@upload.image.purge if @upload.image.attached?
if @upload.destroy
redirect_to root_path
else
render :show
end
end
private
def upload_params
params.require(:upload_form).permit(:title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id, :image, :name).merge(user_id: current_user.id)
end
end
app/models/form_model
class UploadForm
include ActiveModel::Model
attr_accessor :title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id,
:user_id, :image, :name
with_options presence: true do
validates :title
validates :text
validates :cafe_wifi_id
validates :cafe_charging_id
validates :cafe_smoking_id
validates :user_id
validates :image
validates :name
end
with_options numericality: { other_than: 0 } do
validates :cafe_wifi_id
validates :cafe_charging_id
validates :cafe_smoking_id
end
def save(tag_list)
upload = Upload.create(title: title, text: text, url: url, working_day: working_day, day_off: day_off, cafe_wifi_id: cafe_wifi_id, cafe_charging_id: cafe_charging_id, cafe_smoking_id: cafe_smoking_id, user_id: user_id, image: image)
# tag = Tag.create(name: name)
tag_list.each do |tag_name|
tag = Tag.where(name: tag_name).first_or_initialize
tag.save
end
UploadTagRelation.create(upload_id: upload.id, tag_id: tag.id)
end
end
app/models/upload.rb
class Upload < ApplicationRecord
has_one_attached :image
has_one :map
belongs_to :user
has_many :upload_tag_relations, dependent: :destroy
has_many :tags, through: :upload_tag_relations, dependent: :destroy
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :cafe_smoking
belongs_to :cafe_charging
belongs_to :cafe_wifi
end
app/models/upload_tag_relation.rb
class UploadTagRelation < ApplicationRecord
belongs_to :tag
belongs_to :upload
end
app/models/tag.rb
class Tag < ApplicationRecord
has_many :upload_tag_relations
has_many :uploads, through: :upload_tag_relations
validates :name, uniqueness: true
end
試したこと
*コントローラーのcreateアクションの記述に誤りがないか確認してみたところ、@upload=UploadForm.new(upload_params)
でformオブジェクトモデルを渡しているので中間テーブルは保存されるはずができない。
*tag_list = params[:upload_form][:name].split(",")
で配列として処理される記述にしているが、まとまって出力されてしまう。
*formオブジェクト内でUploadTagRelation.create(upload_id: upload.id, tag_id: tag.id)
と記述しているが中間テーブルが保存されない
補足情報(FW/ツールのバージョンなど)
開発環境
・rubymine
・ruby(3.0.1)
・Ruby on rails (6.1.3.1)