前提・実現したいこと
ActiveRecord::NotNullViolation in DrinksController#create
Mysql2::Error: Field 'tag_name' doesn't have a default value
とエラーが出ていて、投稿とタグを一緒に保存したいです
drinks_controller
ruby
1 def new 2 @drink = DrinkTag.new 3 end 4 5 def create 6 @drink = DrinkTag.new(drink_params) 7 if @drink.save 8 redirect_to drinks_path 9 else 10 render 'new' 11 end 12 end 13 14 def destroy 15 Drink.find(params[:id]).destroy 16 redirect_to root_path 17 end 18 19 20 21 private 22 def drink_params 23 params.require(:tweets_tag).permit(:name,:price,:explain,:image,:tag_name).merge(user_id: current_user.id) 24 end 25end 26
drinks/new.html.erb
ruby
1<div class="items-sell-contents"> 2 3 <div class="items-sell-main"> 4 <h2 class="items-sell-title">商品の情報を入力</h2> 5 <%= form_with model: @drink,url: drinks_path, local: true do |f| %> 6 7 8 <%= render 'shared/error_messages', object: f.object %> 9 10 <div class="tag-field"> 11 <%= f.label :tag_name %> 12 <%= f.text_field :tag_name %> 13 </div> 14 <div class="img-upload"> 15 <div class="weight-bold-text"> 16 出品画像 17 <span class="indispensable">必須</span> 18 </div> 19 <div class="click-upload"> 20 <p> 21 クリックしてファイルをアップロード 22 </p> 23 <%= f.file_field :image, id:"item-image" %> 24 </div> 25 </div> 26 27 <div class="new-items"> 28 <div class="weight-bold-text"> 29 商品名 30 <span class="indispensable">必須</span> 31 </div> 32 <%= f.text_area :name, class:"items-text", id:"item-name", placeholder:"商品名(必須 40文字まで)", maxlength:"40" %> 33 <div class="items-explain"> 34 <div class="weight-bold-text"> 35 商品の説明 36 <span class="indispensable">必須</span> 37 </div> 38 <%= f.text_area :explain, class:"items-text", id:"item-info", placeholder:"コーヒーの感想(必須 1,000文字まで)",rows:"7" ,maxlength:"1000" %> 39 </div> 40 </div> 41 42 <div class="price-content"> 43 <div class="price-text"> 44 <span>価格</span> 45 <span class="indispensable">必須</span> 46 </div> 47 <span class="sell-yen">¥</span> 48 <%= f.text_field :price, class:"price-input", id:"item-price", placeholder:"例) 1000" %> 49 </div> 50 51 52 53 54 55 <div class="sell-btn-contents"> 56 <%= f.submit "投稿する" ,class:"sell-btn" %> 57 <%=link_to 'もどる', root_path, class:"back-btn" %> 58 </div> 59 60 </div> 61 <% end %> 62
drink_tag.rb
ruby
1class DrinkTag 2 3 include ActiveModel::Model 4 5 attr_accessor :name,:price,:explain,:user_id,:tag_name 6 7 with_options presence: true do 8 validates :explain 9 validates :price 10 validates :name 11 validates :tag_name 12 # tagとdrinkでnameってカラム名かかってるけど 13 # どっちも今のところpresense: trueでいいけど 14 # タグ付けしなくても投稿できるけど 15 # drinkの名前が必要ってなったらどうする 16 # drink[:name]とかで、drinkのnameにだけ 17 # バリデーション かけることは可能? 18 end 19 20 def save 21 drink = Drink.create(name: name,price: price,explain: explain,user_id: user_id) 22 tag = Tag.where(tag_name: tag_name).first_or_initialize 23 # .first_or_initializeはwhereで検索した条件の 24 # レコードがあれば、そのレコードのインスタンスを返し、 25 # なければ新しくインスタンスを作るメソッドです。 26 27 # tag.rbでtag_nameで一意性の制約をしていて 28 # 被った時に弾いちゃうから.first_or_initialize 29 # が必要 30 tag.save 31 DrinkTagRelation.create(drink_id: drink.id, tag_id: tag.id) 32 end 33 34end
drink.rb
ruby
1class Drink < ApplicationRecord 2 belongs_to :user 3 has_one :trade 4 has_many :drink_tag_relations 5 has_many :tags,through: :drink_tag_relations 6 has_one_attached :image 7 with_options presence: true do 8 validates :name 9 validates :explain 10 end 11end 12
tag.rb
ruby
1class Tag < ApplicationRecord 2 has_many :drink_tag_relations 3 has_many :drinks, through: :drink_tag_relations 4 5 validates :tag_name,uniqueness: true 6 # 存在性の制約はformsで設けて大丈夫だけど 7 # 一意性はモデル単位で設ける必要がある 8end 9
drink_tag_relation.rb
ruby
1class DrinkTagRelation < ApplicationRecord 2 belongs_to :drink 3 belongs_to :tag 4end
試したこと
formObjectを用いたdrink_tag.rbが個人的に怪しそうだな、と思うのですが、
教材と見比べましたが、違いは見受けられないように思います。
パラメーターも
ruby
1{"authenticity_token"=>"T8/aOv7fmGDk6UO/GHiYkODYvpMTH/3tFP6sCW0QPVVaAVh6ZHcAd2xaTQzcuioVXdOOWYAFNHO8u3S0OmnG6Q==", 2 "drink_tag"=> 3 {"tag_name"=>"酸味", 4 "image"=> 5 #<ActionDispatch::Http::UploadedFile:0x00007f8a24b3d318 6 @content_type="image/jpeg", 7 @headers="Content-Disposition: form-data; name=\"drink_tag[image]\"; filename=\"ethiopia.jpg\"\r\n" + "Content-Type: image/jpeg\r\n", 8 @original_filename="ethiopia.jpg", 9 @tempfile=#<File:/var/folders/34/pbcy_n7j1q79hnpm7sbcgl0m0000gn/T/RackMultipart20201204-1452-13ocgpk.jpg>>, 10 "name"=>"エチオピア", 11 "explain"=>"酸味があってアイスもおすすめ!!", 12 "price"=>"1000"}, 13 "commit"=>"投稿する"} 14
とtag_nameはあるのでコントローラーかモデルの方にミスがあるように特にdrink_tag.rbにあるように思えますが、今の自分には分かりません
19: def create 20: @drink = DrinkTag.new(drink_params) => 21: binding.pry 22: if @drink.save 23: redirect_to drinks_path 24: else 25: render 'new' 26: end 27: end [1] pry(#<DrinksController>)> @drink => #<DrinkTag:0x00007fad78565888 @user_id=6> [2] pry(#<DrinksController>)> params => <ActionController::Parameters {"authenticity_token"=>"t9iR1cqdYFujJhDpgSr2eg7svBtkNwF7rrO4rwOdUaKiFhOVUDX4TCuVHlpF6ET/s+eM0fctyOUG9mASVOSqHg==", "drink_tag"=>{"tag_name"=>"", "name"=>"", "explain"=>"", "price"=>""}, "commit"=>"投稿する", "controller"=>"drinks", "action"=>"create"} permitted: false>
と入力した内容が@drink に反映されてないのでやはりモデルに不備がある感じがします
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。