タグ付機能の実装(フリマアプリ)
解決したいこと
タグ付機能を実装するためFormオブジェクトを導入したいのですが、Formオブジェクトの変数@item_formに欲しいカラム(images)が保存できない。
Ruby on Railsでフリマアプリをつくっています。
タグ付機能を実装中です。
このような流れで実装中です。
【Formオブジェクトを導入】
Formオブジェクトを用いた投稿機能を実装 ←現在この部分でエラー中です。。。
Formオブジェクトを用いた編集機能を実装
【タグ付け機能を追加】
タグを保存する機能を実装
タグを編集する機能を実装
解決方法を教えて下さい。
発生している問題・エラー
[9] pry(#<ItemsController>)> @item_form.images
=> nil
@item_form.imagesとしてもnillとなる。
@item_form
=> #<ItemForm:0x00007fe730ac5200
@category_id="4",
@delivery_days_id="3",
@introduction="コーヒーです。",
@item_condition_id="6",
@item_name="コーヒー",
@postage_payer_id="2",
@prefecture_code_id="2",
@price="347",
@user_id=1>
調べてみると、
どうやら@item.imagesにデータが格納されているみたいです。
attr_accessor :images を記入しているはずなのに、@item_form.imagesに反映されていないのはどうしてなのか、、
素人の質問ですみませんがわかる人いましたら教えて欲しいです。
ちなみに関係はないかもしれないのですが、服数枚画像投稿機能と画像プレビュー機能は実装済みです。
コード一覧
item_form.eb
class ItemForm
include ActiveModel::Model
attr_accessor :item_name, :introduction, :price, :delivery_days_id, :images,
:item_condition_id, :postage_payer_id, :prefecture_code_id, :category_id, :user_id
with_options presence: true do
validates :item_name
validates :introduction
validates :images, length: { minimum: 1, maximum: 5, message: "は1枚以上5枚以下にしてください" }
validates_format_of :price, with: /\A[0-9]+\z/
validates :price, numericality: { only_integer: true, greater_than_or_equal_to: 300, less_than_or_equal_to: 9_999_999 },
presence: true
validates :user_id
end
validates :delivery_days_id, :item_condition_id, :postage_payer_id, :prefecture_code_id, :category_id,
numericality: { other_than: 1, message: "を入力してください" }
end
def save
Item.create(item_name: item_name, introduction: introduction, price: price, delivery_days_id: delivery_days_id, images: images,
item_condition_id: item_condition_id, postage_payer_id: postage_payer_id, prefecture_code_id: prefecture_code_id, category_id: category_id, user_id: user_id)
end
items.controller.rb
class ItemsController < ApplicationController
before_action :set_item, except: [:index, :new, :create]
before_action :authenticate_user!, { except: [:index, :show] }
before_action :user_login, only: [:edit, :destroy]
def index
@items = Item.order('created_at DESC')
end
def new
if user_signed_in?
@item_form = ItemForm.new
else
redirect_to user_session_path(@item.id)
end
end
def create
@item_form = ItemForm.new(item_form_params)
if @item_form.valid?
@item_form.save
redirect_to root_path
else
render :new
end
end
def show
end
def edit
if @item.user_id != current_user.id || @item.purchase_history != nil
redirect_to root_path
end
end
def update
if @item.update(item_params)
redirect_to item_path(@item)
else
render :edit
end
end
def destroy
if @item.destroy
redirect_to root_path
else
redirect_to root_path
end
end
private
def item_form_params
params.require(:item_form).permit(:item_name, :introduction, :price, :delivery_days_id, :item_condition_id, :postage_payer_id,
:prefecture_code_id, :category_id, {images: []}).merge(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
def user_login
redirect_to root_path unless current_user.id == @item.user_id
end
end
item.rb
class Item < ApplicationRecord
has_many_attached :images
belongs_to :user
has_one :purchase_history
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :category
belongs_to :item_condition
belongs_to :postage_payer
belongs_to :prefecture_code
belongs_to :delivery_days
end
items.new.html.erb
<div class="items-sell-contents">
<header class="items-sell-header">
<%= link_to image_tag('furima-logo-color.png' , size: '185x50'), "/" %>
</header>
<div class="items-sell-main">
<div id="item-content">
<h2 class="items-sell-title">商品の情報を入力</h2>
<%= form_with model: @item_form, url: items_path,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">
<div id="previews"></div>
<p>
クリックしてファイルをアップロード
</p>
<%= f.file_field :images, id:"item-image",name: 'item[images][]',date: {index: 0} %>
</div>
</div>
<%# /商品画像 %>
<%# 商品名と商品説明 %>
<div class="new-items">
<div class="weight-bold-text">
商品名
<span class="indispensable">必須</span>
</div>
<%= f.text_area :item_name, class:"items-text", id:"item-name", placeholder:"商品名(必須 40文字まで)", maxlength:"40" %>
<div class="items-explain">
<div class="weight-bold-text">
商品の説明
<span class="indispensable">必須</span>
</div>
<%= f.text_area :introduction, class:"items-text", id:"item-info", placeholder:"商品の説明(必須 1,000文字まで)(色、素材、重さ、定価、注意点など)例)2010年頃に1万円で購入したジャケットです。ライトグレーで傷はありません。あわせやすいのでおすすめです。" ,rows:"7" ,maxlength:"1000" %>
</div>
</div>
<%# /商品名と商品説明 %>
<%# 商品の詳細 %>
<div class="items-detail">
<div class="weight-bold-text">商品の詳細</div>
<div class="form">
<div class="weight-bold-text">
カテゴリー
<span class="indispensable">必須</span>
</div>
<%= f.collection_select(:category_id, Category.all, :id, :name, {}, {class:"select-box", id:"item-category"}) %>
<div class="weight-bold-text">
商品の状態
<span class="indispensable">必須</span>
</div>
<%= f.collection_select(:item_condition_id, ItemCondition.all, :id, :name, {}, {class:"select-box", id:"item-sales-status"}) %>
</div>
</div>
<%# /商品の詳細 %>
<%# 配送について %>
<div class="items-detail">
<div class="weight-bold-text question-text">
<span>配送について</span>
<a class="question" href="#">?</a>
</div>
<div class="form">
<div class="weight-bold-text">
配送料の負担
<span class="indispensable">必須</span>
</div>
<%= f.collection_select(:postage_payer_id, PostagePayer.all, :id, :name, {}, {class:"select-box", id:"item-shipping-fee-status"}) %>
<div class="weight-bold-text">
発送元の地域
<span class="indispensable">必須</span>
</div>
<%= f.collection_select(:prefecture_code_id, PrefectureCode.all, :id, :name, {}, {class:"select-box", id:"item-prefecture"}) %>
<div class="weight-bold-text">
発送までの日数
<span class="indispensable">必須</span>
</div>
<%= f.collection_select(:delivery_days_id, DeliveryDays.all, :id, :name, {}, {class:"select-box", id:"item-scheduled-delivery"}) %>
</div>
</div>
<%# /配送について %>
<%# 販売価格 %>
<div class="sell-price">
<div class="weight-bold-text question-text">
<span>販売価格<br>(¥300〜9,999,999)</span>
<a class="question" href="#">?</a>
</div>
<div>
<div class="price-content">
<div class="price-text">
<span>価格</span>
<span class="indispensable">必須</span>
</div>
<span class="sell-yen">¥</span>
<%= f.text_field :price, class:"price-input", id:"item-price", placeholder:"例)300" %>
</div>
<div class="price-content">
<span>販売手数料 (10%)</span>
<span>
<span id='sales-fee'></span>円
</span>
</div>
<div class="price-content">
<span>販売利益</span>
<span>
<span id='profit'></span>円
</div>
</span>
</div>
</div>
<%# /販売価格 %>
<%# 注意書き %>
<div class="caution">
<p class="sentence">
<a href="#">禁止されている出品、</a>
<a href="#">行為</a>
を必ずご確認ください。
</p>
<p class="sentence">
またブランド品でシリアルナンバー等がある場合はご記載ください。
<a href="#">偽ブランドの販売</a>
は犯罪であり処罰される可能性があります。
</p>
<p class="sentence">
また、出品をもちまして
<a href="#">加盟店規約</a>
に同意したことになります。
</p>
</div>
<%# /注意書き %>
<%# 下部ボタン %>
<div class="sell-btn-contents">
<%= f.submit "出品する" ,class:"sell-btn" %>
<%=link_to 'もどる', root_path, class:"back-btn" %>
</div>
<%# /下部ボタン %>
</div>
</div>
<% end %>
<footer class="items-sell-footer">
<ul class="menu">
<li><a href="#">プライバシーポリシー</a></li>
<li><a href="#">フリマ利用規約</a></li>
<li><a href="#">特定商取引に関する表記</a></li>
</ul>
<%= link_to image_tag('furima-logo-color.png' , size: '185x50'), "/" %>
<p class="inc">
©︎Furima,Inc.
</p>
</footer>
</div>
0