質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

2464閲覧

mdSQLite3::SQLException: no such table: のテーブル名がおかしい

rosalia

総合スコア20

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/07/27 11:41

編集2020/07/31 07:23

リンク内容
こちらの記事を参考にアプリに通知機能を導入しようとしているのですが、いいねボタンを押した際に

ActiveRecord::StatementInvalid in FavoritesController#create SQLite3::SQLException: no such table: main.visiteds: INSERT INTO "notifications" ("visitor_id", "visited_id", "micropost_id", "action", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?)

といったような、visitedsというようなテーブルはないと言われます。visited_idというカラムがnotificationモデルにあるのですが、何故かここでそのカラムが挙げられていて困惑しています。この場合どのようなことが原因として考えられるのでしょうか。

試したこと

・tableの作り直し
・サーバーの再起動
・コマンドでインスタンスの生成を試みましたが

pry(main)> user.active_notifications.create(visited_id: 2, micropost_id: 116, action: 'like') ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: main.visiteds: INSERT INTO "notifications" ("visitor_id", "visited_id", "micropost_id", "action", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) from /Users/ryoga_h/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:147:in `initialize' Caused by SQLite3::SQLException: no such table: main.visiteds from /Users/ryoga_h/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:147:in `initialize'

と、こちらでもvisitedsテーブルが見つからないと表示されます。

notificationsテーブル

create_table "notifications", force: :cascade do |t| t.integer "visitor_id", null: false t.integer "visited_id", null: false t.integer "micropost_id" t.integer "comment_id" t.string "action", null: false t.boolean "checked", default: false, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["comment_id"], name: "index_notifications_on_comment_id" t.index ["micropost_id"], name: "index_notifications_on_micropost_id" t.index ["visited_id"], name: "index_notifications_on_visited_id" t.index ["visitor_id"], name: "index_notifications_on_visitor_id" end

micropost.rb

def create_notification_like!(current_user) # すでに「いいね」されているか検索 temp = Notification.where(["visitor_id = ? and visited_id = ? and micropost_id = ? and action = ? ", current_user.id, user_id, id, 'like']) # いいねされていない場合のみ、通知レコードを作成 if temp.blank? notification = current_user.active_notifications.build( micropost_id: id, visited_id: user_id, action: 'like' ) # 自分の投稿に対するいいねの場合は、通知済みとする if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? end end

favoritesコントローラ

def create @micropost = Micropost.find(params[:micropost_id]) current_user.like(@micropost) redirect_back(fallback_location: root_url) @micropost.create_notification_like!(current_user) end

Notification.rb

class Notification < ApplicationRecord default_scope -> { order(created_at: :desc) } belongs_to :visitor, class_name: "User", foreign_key: "visitor_id", optional: true belongs_to :visited, class_name: "User", foreign_key: "visited_id", optional: true belongs_to :micropost, optional: true belongs_to :comment, optional: true end

User.rb

has_many :active_notifications, class_name: 'Notification', foreign_key: 'visitor_id', dependent: :destroy has_many :passive_notifications, class_name: 'Notification', foreign_key: 'visited_id', dependent: :destroy

マイグレーション

class CreateNotifications < ActiveRecord::Migration[5.1] def change create_table :notifications do |t| t.references :visitor, foreign_key: true, null: false t.references :visited, foreign_key: true, null: false t.references :micropost, foreign_key: true t.references :comment, foreign_key: true t.string :action, null: false t.boolean :checked, default: false, null: false t.timestamps end # rails5.0以降はt.referencesでindexが自動生成される end end

optinoal:trueを外した後

[16] pry(main)> a = user.active_notifications.create!(action:'like', micropost_id: 100,visited_id: 4) (0.1ms) begin transaction User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]] (0.1ms) rollback transaction ActiveRecord::RecordInvalid: Validation failed: Miropost must exist, Comment must exist from /Users/ryoga_h/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activerecord-5.1.7/lib/active_record/validations.rb:78:in `raise_validation_error'

学習の身で自己解決力も乏しく自分では解決することができませんでした。どなたかご教授頂けると嬉しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

model Notification に belongs_to visitor ってしてませんか?
この場合 「Visitor モデルと関連がある」とrailsは解釈しますので、上のエラーとなります。
多分 User ですよね?
belongs_to visitor class_name: 'User',foreign_key: :visitor_idとかしてください。
visited も

t.references :visitor, foreign_key: true, null: false t.references :visited, foreign_key: true, null: false t.references :micropost, foreign_key: true t.references :comment, foreign_key: true
とこれらにみな foreign_key: true がついています。
これは database に対して、

これらの id が実際に存在するものの id が入力されていることを確認してくれ
これらの id の相方が削除されそうになったらエラーにしてくれ

という指示を出していることになります。
ですので、これら4つのidを全部指定しなければなりません

投稿2020/07/27 23:11

編集2020/07/31 10:38
winterboum

総合スコア23284

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rosalia

2020/07/29 06:34

質問文を編集させて頂きました。class_nameはちゃんと記述されているようでした。
winterboum

2020/07/29 09:52

user.active_notifications.create でエラーですね。 ということは model User ではなく ActiveNotification が問題です
rosalia

2020/07/29 10:13

User.rbのコードも載せさせて頂きました。おかしなところは見当たらなかったため、念のため参考にしたサイトからコピペしたのですが解決に至りませんでした... 他に思い当たる点はないでしょうか?何度もお手数をかけ申し訳ないです。
winterboum

2020/07/29 10:15

ですから、エラーはuser.active_notifications.create なので ということは model User ではなく ActiveNotification が問題です
rosalia

2020/07/29 10:19

理解不足で申し訳ありません。active_notificationsの関連づけが失敗しているということでしょうか?
winterboum

2020/07/29 11:59

すみません、理解できなかったの無理もない、私がcode見損なってました。 関連の定義におかしな所は見当たりません。 あえて言うと table定義で null: false しているので、関連で optional: true してもだめです。関連無しでsaveするとrailsのvalidationは通りますが、DBがエラーはを返す。 エラーメッセージがちょっと違うのが気になりますが、 user.active_notifications.create(visited_id: 2,、、、、、 で、visiter_id を指定していないですね。それが影響しているかも。
winterboum

2020/07/29 20:27

舌足らず。。。 かも、と自信なさげなのは 関連が定義してあるので user.active_notifications.create にて notification に user.id がセットされますが、今回user.idをセットすべき場所が二箇所ある、何方に入れてくれるのか、が寝ぼけた頭ではパット判断できなくなってました。 改めて考えてみて、foreign_keyに指定されてる visiter_id だろうと思ったのですが、すると「このエラーが良くわからん」という点は変わりなし。 両方にデータが入っているかどうか確認していただけないでしょうか。 方法は2つ。 1. 意味をなさないoptional: true をはずして実行してvalidationに掛かるかどうか 2. log にある 発行された Insert文を確認する。
rosalia

2020/07/31 07:20

返答が遅れしまいすみません。notificationsのカラム全てのoptional:trueを外した結果、いいねボタンを押した際のno such tableのエラーが出なくなりました。その代わり、追加文のように1つ気になることがあるのですが、notificationsのcomment_idとmicropost_idは必ずしも埋まっているわけではないのでoptional:trueが必要だと思うのですが、そうすると最初のようなno such tableエラーが出てしまします。とすると、presence:trueとnull:falseを削除するしかないように思えるのですがどうなのでしょうか?
winterboum

2020/07/31 07:47

「追加文のように」ってどれでしょう、、、、 その新たに出たエラー全文と そのエラーが出た時のcodeを追加してください
rosalia

2020/07/31 08:02

申し訳ないです。文章ミスでしたので先ほどのコメントは無視してください.... 現状を報告させて頂くと、winterboumさんの言う通りoptional:trueを全て外してみるno such tables: main.visiteds... のエラーは消えたのですが、代わりに追加文のようなvalidationエラーが発生するようになりました。恐らくvalidatioinエラーの理由はbelongs_toのせいだと思います。comment_id,micropost_idは必ずしも埋まっているわけではないので、optional:trueを記述したいのですが、それができない状況です。 本当にどうしたらいいかわからず、手詰まりといた感じです...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問