ruby-on-rails - ActiveRecord::StatementInvalid (SQLite3::SQLException: no such table: main.contacts) Rails 中的友谊
问题描述
我正在尝试在 Rails 中建立友谊,我将其命名为“连接”,通过用户到用户的关联来创建朋友,我将其命名为“联系人”。我一直在关注一个教程,并且进展顺利,但是当我尝试在 rails 控制台中发送朋友/联系人请求以测试以确保它有效时遇到了麻烦:
2.7.0 :043 > user4.contact_request(user5)
Connection Exists? (5.7ms) SELECT 1 AS one FROM "connections" WHERE "connections"."user_id" = ? AND "connections"."contact_id" = ? LIMIT ? [["user_id", 7], ["contact_id", 8], ["LIMIT", 1]]
TRANSACTION (0.2ms) begin transaction
Connection Create (1.8ms) INSERT INTO "connections" ("user_id", "contact_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 7], ["contact_id", 8], ["created_at", "2021-04-20 00:40:23.578180"], ["updated_at", "2021-04-20 00:40:23.578180"]]
TRANSACTION (0.1ms) rollback transaction
Traceback (most recent call last):
4: from (irb):42
3: from (irb):43:in `rescue in irb_binding'
2: from app/models/user.rb:49:in `contact_request'
1: from app/models/user.rb:50:in `block in contact_request'
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such table: main.contacts)
我不知道我在 PostgresQL 而不是 SQLite 上构建这个 rails 项目是否会有所不同。
连接控制器:
class ConnectionsController < ApplicationController
before_action :authenticate_user!
before_action :set_user
# GET /connections or /connections.json
def index
@connections = Connection.all
end
# GET /connections/1 or /connections/1.json
def show
end
# GET /connections/new
def new
current_user.contact_request(@user)
current_user.reload
end
# GET /connections/1/edit
def edit
end
# POST /connections or /connections.json
def create
current_user.accept_request(@user)
current_user.reload
end
# PATCH/PUT /connections/1 or /connections/1.json
def update
respond_to do |format|
if @connection.update(connection_params)
format.html { redirect_to @connection, notice: "Connection was successfully updated." }
format.json { render :show, status: :ok, location: @connection }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @connection.errors, status: :unprocessable_entity }
end
end
end
# DELETE /connections/1 or /connections/1.json
def destroy
current_user.reject_request(@user)
current_user.reload
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Only allow a list of trusted parameters through.
def connection_params
params.fetch(:connection, {})
end
end
连接模型:
class Connection < ApplicationRecord
belongs_to :user
belongs_to :contact, class_name: 'User'
enum status: {pending: 0, requested: 1, accepted: 2, blocked: 3}
# id: 1
# contact: 2
# user_id: 1, contact_id: 2, status: :requested
# user_id: 2, contact_id: 1, status: :pending
end
用户型号:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :developments, dependent: :destroy
has_many :connections
has_many :connections, dependent: :destroy
has_many :contacts, -> { where connections: { status: :accepted }}, through: :connections
has_many :requested_contacts, -> { where connections: {status: :requested}}, through: :connections, source: :contact
has_many :pending_contacts, -> { where connections: { status: :pending }}, through: :connections, source: :contact
has_many :blocked_contacts, -> { where connections: { status: :blocked }}, through: :connections, source: :contact
# has_many :connections_inverse, class_name: 'Connection', foreign_key: :contact_id
# has_many :contacts_inverse, through: :connections_inverse, source: :user
# def all_contacts
# contacts + contacts_inverse
# end
def has_connection?(contact)
return true if self == contact
connections.map(&:contact_id).include?(contact.id)
end
def requested_contacts_with?(contact)
return false if self == contact
requested_contacts.map(&:id).include?(contact.id)
end
def pending_contacts_with?(contact)
return false if self == contact
pending_contacts.map(&:id).include?(contact.id)
end
def contacts_with?(contact)
return false if self == contact
contacts.map(&:id).include?(contact.id)
end
def reject_request(contact)
transaction do
Connection.find_by(user: self, contact: contact)&.destroy!
Connection.find_by(user: contact, contact: self)&.destroy!
end
end
def contact_request(contact)
unless self == contact || Connection.where(user: self, contact: contact).exists?
transaction do
Connection.create(user: self, contact: contact, status: :pending)
Connection.create(user: contact, contact: self, status: :requested)
end
end
end
def accept_request(contact)
transaction do
Connection.find_by(user: self, contact: contact, status: [:requested])&.accepted!
Connection.find_by(user: contact, contact: self, status: [:pending])&.accepted!
end
end
def reject_request(contact)
transaction do
Connection.find_by(user: self, contact: contact)&.destroy!
Connection.find_by(user: contact, contact: self)&.destroy!
end
end
end
架构:
ActiveRecord::Schema.define(version: 2021_04_19_034240) do
create_table "connections", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "contact_id", null: false
t.integer "status", limit: 1, default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["contact_id"], name: "index_connections_on_contact_id"
t.index ["user_id"], name: "index_connections_on_user_id"
end
create_table "dashboards", force: :cascade do |t|
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "developments", force: :cascade do |t|
t.string "dev_title"
t.text "dev_description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "lots", force: :cascade do |t|
t.string "lot_title"
t.text "lot_description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "development_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "connections", "contacts"
add_foreign_key "connections", "users"
end
连接迁移:
class CreateConnections < ActiveRecord::Migration[6.1]
def change
create_table :connections do |t|
t.references :user, null: false, foreign_key: { to_table: :users}
t.references :contact, null: false, foreign_key: {to_table: :users}
t.integer :status, default: 0, limit: 1
t.timestamps
end
end
end
我对迁移的工作方式有点困惑,所以我直接编辑了迁移文件以添加:
foreign_key: { to_table: :users}
foreign_key: {to_table: :users}
根据建议修复数据库问题,但我的理解是迁移文件总是需要通过在终端中删除、创建和滚动它们来进行编辑,所以我不确定上述修复是否适用于我尝试做的方式它。
编辑:
我不认为这是数据库的问题,但我在网上看到的其他帖子似乎指出这是迁移文件中的问题。如果有人有任何见解,我将不胜感激。
解决方案
推荐阅读
- c# - 停止来自 Animator 的特定动画
- ios - 基于其中的 UICollectionView 单元格的 tableview 单元格的动态高度
- java - 使用 JAVA 在 Android Studio 中使用 RadioButtons 和 Buttons
- python - 在 django 中从视图和 url 加载 url 时出现问题
- php - 使用自定义字段分组对象
- objective-c - ExpoKit:选择器“moduleRegistry”没有已知的实例方法
- javascript - JavaScript forEach:改变元素
- java - 如何使用 Apple 启用 Spring Boot 应用程序的 SSO oauth2
- python - python重复数据删除的高CPU和内存利用率
- html - 无论如何,是否只使用 CSS 在标签中的特定文本上添加 CSS?