我创建了一个空白的rails应用程序(rails new cheese_shop
),有两个模型和一个连接表。我想在创建时创建一个奶酪店并指定它包含哪些奶酪,如下所示:
cheeses = [
Cheese.create!(name: "Bree"),
Cheese.create!(name: "Kačkavalj"),
]
Shop.create! name: "The Whistling Cheese", cheeses: cheeses
但是,我收到此错误:
SQLite3::ConstraintException: NOT NULL constraint failed: stocks.shop_id: INSERT INTO "stocks" ("cheese_id", "created_at", "updated_at") VALUES (?, ?, ?)
显然,我在创建商店时没有将商店ID插入stocks
表。是否有可能解决这个问题,而不必分两步完成(即没有先创建商店,然后添加奶酪?)
class Cheese < ActiveRecord::Base
has_many :shops, through: :stocks
has_many :stocks
end
class Shop < ActiveRecord::Base
has_many :cheeses, through: :stocks
has_many :stocks
end
class Stock < ActiveRecord::Base
belongs_to :shop
belongs_to :cheese
end
class CreateTables < ActiveRecord::Migration
def change
create_table :cheeses do |t|
t.string :name, null: false
t.timestamps null: false
end
create_table :shops do |t|
t.string :name, null: false
t.timestamps null: false
end
create_table :stocks do |t|
t.integer :shop_id, null: false
t.integer :cheese_id, null: false
t.integer :amount
t.float :price
end
end
end
答案 0 :(得分:1)
也许您应该尝试使用嵌套属性:
class Shop < ActiveRecord::Base
has_many :cheeses, through: :stocks
has_many :stocks
accepts_nested_attributes_for :stocks
end
然后您将能够执行以下操作:
cheese = Cheese.create!(name: "Bree")
params = { attrib: { name: "The Whistling Cheese", stocks_attributes: { cheese_id: cheese.id} } }
Shop.create params[:attrib]
这里是doc:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
答案 1 :(得分:0)
事实证明,Rails分两步创建关联,首先省略商店ID,然后在一个事务中设置商店ID以UPDATE
。所以NOT NULL
约束导致问题。
更改此内容:
t.integer :shop_id, null: false
t.integer :cheese_id, null: false
......对此:
t.integer :shop_id
t.integer :cheese_id, null: false
...解决了这个问题,虽然我对此不满意,因为现在我不能依靠数据库来确保数据的完整性。