レシピ投稿サイトを作っています。
投稿ページで材料(material)を入力した分だけ一括でテーブルに保存できるように
しようと思っています。
上記サイトを参考にしてコードを書いています。
それから複数のテーブルにも保存できるような形にしています。
class Recipe < ApplicationRecord belongs_to :user has_one_attached :image has_one :chef has_many :material end
class Material < ApplicationRecord belongs_to :recipe end
class Chef < ApplicationRecord belongs_to :recipe end
class Form::Base include ActiveModel::Model include ActiveModel::Callbacks include ActiveModel::Validations include ActiveModel::Validations::Callbacks include ActiveModel::Attributes end
class Form::CookRecipe < Form::Base include ActiveModel::Model FORM_COUNT = 3 attr_accessor :video, :title, :text, :image, :user_id, :cook_1, :cooks with_options presence: true do validates :video validates :title validates :text validates :image end def initialize(attributes = {}) super attributes self.cooks = FORM_COUNT.times.map { Material.new() } unless self.cooks.present? end def cooks_attributes=(attributes) self.cooks = attributes.map { |_, v| Material.new(v) } end def save recipe = Recipe.create(user_id: user_id, video: video, title: title, text: text, image: image) Chef.create(cook_1: cook_1, recipe_id: recipe.id) Material.transaction do self.cooks.map(&:save!) end return true rescue => e return false end end
class RecipesController < ApplicationController def index @recipes = Recipe.all end def new @cook_recipe = Form::CookRecipe.new end def create @cook_recipe = Form::CookRecipe.new(recipe_params) url = params[:form_cook_recipe][:video] url = url.last(11) @cook_recipe.video = url if @cook_recipe.save redirect_to root_path else render :new end end def show @recipe = Recipe.find(params[:id]) end private def recipe_params params.require(:form_cook_recipe).permit(:video, :title, :text, :image, :cook_1, cooks_attributes: [:vegetable_1]).merge(user_id: current_user.id) end end
<h2 class="page-heading">簡単レシピ投稿</h2> <%= form_with model: @cook_recipe, url: recipes_path, local: true do |f|%> <div class="field"> <%= f.label :title, "料理名" %><br /> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :text, "説明文" %><br /> <%= f.text_area :text, class: :form__text %> </div> <%= f.fields_for :cooks do |field| %> <div class="field"> <%= field.label :vegetable_1, "材料" %><br /> <%= field.text_area :vegetable_1, class: :form__text %> </div> <% end %> <div class="field"> <%= f.label :cook_1, "作り方" %><br /> <%= f.text_area :cook_1, class: :form__text %> </div> <div class="field"> <%= f.label :image, "料理の画像" %><br /> <%= f.file_field :image %> </div> <div class="field"> <%= f.label :video, "Youtube URL" %><br /> <%= f.text_field :video %> </div> <div class="actions"> <%= f.submit "投稿", class: :form__btn %> </div> <% end %>
解決したいこと
パラメーターは送信できるのですが、一括保存をしたいMaterialテーブルにだけ保存ができません。
↓パラメーターの送信状況です。
10: def create 11: @cook_recipe = Form::CookRecipe.new(recipe_params) 12: url = params[:form_cook_recipe][:video] 13: url = url.last(11) 14: @cook_recipe.video = url => 15: binding.pry 16: 17: if @cook_recipe.save 18: redirect_to root_path 19: else 20: render :new 21: end 22: end [1] pry(#<RecipesController>)> params => <ActionController::Parameters {"authenticity_token"=>"m9wXOBjyMuu/aZOcthfY2WhpF8dy/Xsc1pQkKj9MTP7Ufty6K3npGknmuBpErMD7Upd+Mr35cR7fR2imElB61A==", "form_cook_recipe"=><ActionController::Parameters {"title"=>"pooppopopo", "text"=>"tatatatatatatattata", "cooks_attributes"=>{"0"=>{"vegetable_1"=>"ko"}, "1"=>{"vegetable_1"=>"mu"}, "2"=>{"vegetable_1"=>"gi"}}, "cook_1"=>"eeeeee", "image"=>#<ActionDispatch::Http::UploadedFile:0x00007feb02897d90 @tempfile=#<Tempfile:/var/folders/vq/prgw2yxj1ns327cvwpw4plrc0000gn/T/RackMultipart20201105-1740-xxn2lg.jpg>, @original_filename="7ac726af05cc3a5a5cdea8819379ede6.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"form_cook_recipe[image]\"; filename=\"7ac726af05cc3a5a5cdea8819379ede6.jpg\"\r\nContent-Type: image/jpeg\r\n">, "video"=>"VgmYtFxp-SY"} permitted: false>, "commit"=>"投稿", "controller"=>"recipes", "action"=>"create"} permitted: false> [2] pry(#<RecipesController>)> @cook_recipe => #<Form::CookRecipe:0x00007feaffbeeb40 @attributes=#<ActiveModel::AttributeSet:0x00007feaffbeea28 @attributes={}>, @cook_1="eeeeee", @cooks= [#<Material:0x00007feaffc06790 id: nil, vegetable_1: "ko", vegetable_2: nil, vegetable_3: nil, vegetable_4: nil, vegetable_5: nil, vegetable_6: nil, vegetable_7: nil, vegetable_8: nil, vegetable_9: nil, vegetable_10: nil, vegetable_11: nil, vegetable_12: nil, vegetable_13: nil, vegetable_14: nil, vegetable_15: nil, recipe_id: nil, created_at: nil, updated_at: nil>, #<Material:0x00007feb099f41f0 id: nil, vegetable_1: "mu", vegetable_2: nil, vegetable_3: nil, vegetable_4: nil, vegetable_5: nil, vegetable_6: nil, vegetable_7: nil, vegetable_8: nil, vegetable_9: nil, vegetable_10: nil, vegetable_11: nil, vegetable_12: nil, vegetable_13: nil, vegetable_14: nil, vegetable_15: nil, recipe_id: nil, created_at: nil, updated_at: nil>, #<Material:0x00007feafc7d3ae0 id: nil, vegetable_1: "gi", vegetable_2: nil, vegetable_3: nil, vegetable_4: nil, vegetable_5: nil, vegetable_6: nil, vegetable_7: nil, vegetable_8: nil, vegetable_9: nil, vegetable_10: nil, vegetable_11: nil, vegetable_12: nil, vegetable_13: nil, vegetable_14: nil, vegetable_15: nil, recipe_id: nil, [3] pry(#<RecipesController>)> exit
どうにか保存できる形にしたいです。
どの点が不足しているなどご指摘いただけますでしょうか。
恐縮ですがお力を貸していただけますと幸いです。
よろしくお願いいたします。
パラメーター達は画像でなく<code>を使ってtextで載せてください。読みにくいし検索もできない。