@Ogw17_08 (小川 祐汰)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【データベース保存ができません】

Q&A

Closed

解決したいこと

データベースに情報を保存したいです。

例)
Ruby on Railsで画像投稿Webアプリをつくっています。
記事&画像を投稿する際にうまくデータベースに保存されません。
解決方法を教えて下さい。

発生している問題・エラー

tarted POST "/photos" for ::1 at 2021-05-21 13:03:38 +0900
Processing by PhotosController#create as HTML
  Parameters: {"authenticity_token"=>"hiljVFAc5ExG+Kxbnr/F7QTHrPeDovKOc6pddNj1RJ30sjTg3XK+lFDYdAouEhP6lBo028Bl0N77vNjM1WU8Tw==", "photo"=>{"title"=>"麻婆豆腐", "date"=>"5/20", "image"=>"https://cdn.sbfoods.co.jp/recipes/07818_l.jpg", "text"=>"今日の晩御飯"}, "commit"=>"SEND"}
  User Load (2.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ app/controllers/photos_controller.rb:23:in `photo_params'
   (0.3ms)  BEGIN
  ↳ app/controllers/photos_controller.rb:11:in `create'
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  ↳ app/controllers/photos_controller.rb:11:in `create'
   (0.3ms)  ROLLBACK
  ↳ app/controllers/photos_controller.rb:11:in `create'
   (0.3ms)  BEGIN
  ↳ app/controllers/photos_controller.rb:13:in `create'
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  ↳ app/controllers/photos_controller.rb:13:in `create'
   (0.3ms)  ROLLBACK
  ↳ app/controllers/photos_controller.rb:13:in `create'
  Rendering photos/new.html.erb within layouts/application
  Rendered photos/new.html.erb within layouts/application (Duration: 0.9ms | Allocations: 417)
[Webpacker] Everything's up-to-date. Nothing to do
Completed 200 OK in 54ms (Views: 12.8ms | ActiveRecord: 4.0ms | Allocations: 15930)

該当するソースコード

class PhotosController < ApplicationController
  def index
  end

  def new
    @photo = Photo.new
  end

  def create
    # binding.pry
    Photo.create(photo_params) #createメソッドの引数に使用して、tweetsテーブルへ保存できるよう
    @photo = Photo.new(photo_params)
    if @photo.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def photo_params
    params.require(:photo).permit(:title, :date, :image, :text).merge(user_id: current_user.id)
  end
end

例)

<div class="contents row">
  <div class="container">
    <h3>投稿する</h3>
    <%= form_with(model: @photo, url: photos_path, local: true) do |form| %>
      <%= form.text_field :title, placeholder: "Title" %>
      <%= form.text_field :date, placeholder: "Date" %>
      <%= form.text_field :image, placeholder: "Image Url" %>
      <%# <%= image_tag photo.image, class: 'photo-image' if photo.image.attached? %> 
      <%= form.text_area :text, placeholder: "Text", rows: "20", cols: "60" %>
      <%= form.submit "SEND" %>
    <% end %>
  </div>
</div>
Rails.application.routes.draw do
  devise_for :users
  root to: "photos#index"
  resources :photos, only: [:index, :new, :create]
end
class Photo < ApplicationRecord
  belongs_to :user
  has_one_attached :image

  validates :title, presence: true
  validates :text,  presence: true
  validates :date,  presence: true
end
class CreatePhotos < ActiveRecord::Migration[6.0]
  def change
    create_table :photos do |t|
      t.string :title,    null: false
      t.text   :text,     null: false
      t.date   :date,     null: false
      t.references :user, foreign_key: true

      t.timestamps
    end
  end
end

自分で試したこと

binding.pryするとparamsが空でした。
permitがfalseで帰ってきているのでストロングパラメーター内のpermitを確認しましたが大丈夫そうです。
form_withの記述の仕方が間違っているのではないかと思い、url指定しました。

0 likes

4Answer

ログの中にフォーム送信内容はあるみたいなので、データは来ていると思います。

  Parameters: {"authenticity_token"=>"hiljVFAc5ExG+Kxbnr/F7QTHrPeDovKOc6pddNj1RJ30sjTg3XK+lFDYdAouEhP6lBo028Bl0N77vNjM1WU8Tw==", "photo"=>{"title"=>"麻婆豆腐", "date"=>"5/20", "image"=>"https://cdn.sbfoods.co.jp/recipes/07818_l.jpg", "text"=>"今日の晩御飯"}, "commit"=>"SEND"}
    Photo.create(photo_params) #createメソッドの引数に使用して、tweetsテーブルへ保存できるよう
    @photo = Photo.new(photo_params)
    if @photo.save

ここがちょっと気になるんですが、ログ上エラーが出てるのはapp/controllers/photos_controller.rb:13:in createなので多分if @photo.saveから来ているんだと思いますが、なんで

  • Photo.create(photo_params)

これがあるんですか?そのすぐ下にPhoto.new -> saveがあるんで同じものをこれだと2つ作りませんか?

現在どういうエラーが起きているのかわからないので、

    if @photo.save
      redirect_to root_path
    else
p @photo.errors
      render :new
    end

こういう風にしてエラーの内容をログに出してみてはどうでしょうか?

1Like

多分ですけど、

models/photo.rb
  has_one_attached :image

なのにフォーム送信内容は

"image"=>"https://cdn.sbfoods.co.jp/recipes/07818_l.jpg"

という単純な文字列なので、これが原因かも?

ActiveStorageには普通ファイル(オブジェクト)を入れるはずなので、単純な文字列では保存できないと思います。

URLから保存するのなら、Rails側でURLを受け取った後にURLのファイル(今回は写真)をダウンロードしてファイルのオブジェクトにしてからimageにattachする必要があるのかなと。
いきなりcontroller内でデバックするのは難しいので、rails consoleでどういう風に処理するかを試してみると楽だと思います。

$ rails c
> photo = Photo.new
> url = "http://..."
> #ダウンロードする
> photo.image.attach ... # https://railsguides.jp/active_storage_overview.html#file-io-objects%E3%82%92%E3%82%A2%E3%82%BF%E3%83%83%E3%83%81%E3%81%99%E3%82%8B
0Like

photoモデルにimageのバリデーションを記述していないことでエラーが解消されました。
Photo.create(photo_params) #createメソッドの引数に使用して、tweetsテーブルへ保存できるよう
@photo = Photo.new(photo_params)
if @photo.save
上記の記述を指摘していただいた件ですが、投稿をすると同じものが2つ投稿されるということで悩んでいたので、これを見て解消することができました。
@github0013@github さんありがとうございます!!

0Like

Your answer might help someone💌