我有一个名为admin的文件夹,其中有一个生成的脚手架,名为products,其中也有primary_key, id,更改为ect。然后我创建了一个叫做cart_products的模型,它有一个belongs_to :product
。当我试着用它的时候:@cart.cart_products.create(product: @product, quantity:)
,它抛出一个名称错误,说
Rails找不到产品关联的有效模型。请在关联声明中提供:class_name选项。如果:class_name已经提供,确保它是一个ActiveRecord::Base子类。
因此,我将belongs_to更改为belongs_to :product, :class_name => "Admin::Product"
,这是产品模型的名称。现在我得到一个
ActiveRecord::StatementInvalid - SQLite3::SQLException: no such table: main.products
在我的数据库中它被保存为create_table "admin_products", primary_key: "ect", force: :cascade do |t|
时,main.products
来自哪里?
我的代码如下:
# controllers/home/cart_controller.rb
class Home::CartController < HomeController
def add
@product = Admin::Product.find_by(ect: params[:ect])
# Code breaks on next line
@cart.cart_products.create(product: @product, quantity:)
end
end
# models/cart_product.rb
class CartProduct < ApplicationRecord
belongs_to :product, class_name: "Admin::Product"
belongs_to :cart
end
# models/admin/product.rb
class Admin::Product < ApplicationRecord
has_many :cart_products
has_many :carts, through: :cart_products
end
end
# models/admin.rb
module Admin
def self.table_name_prefix
"admin_"
end
end
我要访问的数据库是:
# associated with models/admin/product.rb
create_table "admin_products", primary_key: "ect", force: :cascade do |t|
t.string "title"
t.decimal "price"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
# associated with models/cart_product.rb
class CreateCartProducts < ActiveRecord::Migration[7.0]
def change
create_table :cart_products do |t|
t.belongs_to :product, null: false, foreign_key: true
t.belongs_to :cart, null: false, foreign_key: true
t.integer :quantity
t.timestamps
end
end
end
必须告诉rails表名:
# app/models/admin/product.rb
module Admin
class Product < ApplicationRecord
self.table_name = "admin_products"
end
end
或者为Admin模块中的每个模型表添加前缀。
# app/models/admin.rb
module Admin
def self.table_name_prefix
"admin_"
end
end
回滚CreateCartProducts
迁移并更新它以修复外键约束:
# NOTE: by default when foreign key constraint is created
# the name of the foreign table is inferred from
# the argument `:product`. There is no `products` table,
# which is why SQLite complains about it in the error;
# custom primary key has to be also specified.
# t.belongs_to :product, null: false, foreign_key: true
t.belongs_to :product, null: false,
foreign_key: { to_table: :admin_products, primary_key: "ect" }
再次运行迁移。这应该可以修复它。
此外,最好设置PostgreSQL进行开发。当尝试运行该迁移时,它会引发错误,但SQLite似乎可以进行迁移,但稍后会抱怨。https://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html method-i-table_name
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html method-i-add_reference
总是在脚手架之后运行任何模型
rails db:迁移
您的模型文件是否admin/product.rb
class Admin::Product < ApplicationRecord
如果是,那么你需要有class_name与下面的关联
belongs_to :product, class_name: "Admin::Product"