在 Rails 中播种数据库时出错 我没有使用的属性错误



我正在奥丁项目中从事航班预订项目。我正试图建立一个数据库,其中包含往返10个城市的60天航班。当我为数据库播种时,我会得到以下错误:

创建的数据库'flight_booker_development'创建的数据库'flight_booker_test'#机场:0x00007f003f0c6f20轨道中止!ActiveModel::MissingAttributeError:无法写入未知属性flight_id

raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
^^^^^ /home/stuart/repos/flight-booker/db/seeds.rb:23:in `block (4 levels) in <main>'

/home/stuart/reso/flight booker/db/seeds.rb:22:在times' /home/stuart/repos/flight-booker/db/seeds.rb:22:in块中(3个级别)在'/home/stuart/reso/flight booker/db/seeds.rb:21:在times' /home/stuart/repos/flight-booker/db/seeds.rb:21:in块中(2级)在'/home/stuart/reso/flight booker/db/seeds.rb:15:inblock in <main>' /home/stuart/repos/flight-booker/db/seeds.rb:14:in'任务:TOP=>db:重置=>db:setup=>db:seed(查看完整跟踪使用--trace)运行任务

问题似乎是它试图编写一个我没有使用的属性。这是我的seeds.rb文件:

require "faker"
airports = %w[LAX DFW NYC DEN BOS MIA HOU PIT POR MIN]
airports.each { |city_code| Airport.create!(city_code: city_code) }
Airport.all.each do |departure|
Airport.all.each do |arrival|
next if departure == arrival
puts departure
duration = rand(100..300)
flight_number = rand(1000..1999)
frequency = rand(3..5)
60.times do
frequency.times do
Flight.create!(
origin_id: departure,
destination_id: arrival,
duration: duration,
flight_number: flight_number,
departure_time: Faker::Time.forward(days: 60, period: :all)
)
end
end
end
end

我曾试图使用flight_id来保存航班号,但后来改变了,因为我意识到我的预订表中有一个flight _id列。不过,我现在没有处理预订表。我之前也遇到过同样的错误,然后我进行了迁移,将flight_id和add_flight编号删除到flights表中。这是当前的方案。rb

ActiveRecord::Schema[7.0].define(version: 2022_12_09_210422) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "airports", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "city_code"
end
create_table "bookings", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id", null: false
t.bigint "flight_id", null: false
t.index ["flight_id"], name: "index_bookings_on_flight_id"
t.index ["user_id"], name: "index_bookings_on_user_id"
end
create_table "flights", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "destination"
t.string "origin"
t.datetime "departure_time"
t.integer "duration"
t.bigint "destination_id", null: false
t.bigint "origin_id", null: false
t.integer "flight_number"
t.index ["destination_id"], name: "index_flights_on_destination_id"
t.index ["origin_id"], name: "index_flights_on_origin_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", null: false
t.datetime "updated_at", null: 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 "bookings", "flights"
add_foreign_key "bookings", "users"
add_foreign_key "flights", "airports", column: "destination_id"
add_foreign_key "flights", "airports", column: "origin_id"
end

这里是models/flight.rb文件:

class Flight < ApplicationRecord
belongs_to :booking, foreign_key: "flight_id"
has_one :origin_id, class_name: "Airport"
has_one :destination_id, class_name: "Airport"
validates :departure_time, presence: true
validates :duration, presence: true
validates :flight_number, presence: true
end

这是flight_id唯一出现在任何地方的地方,但如果我删除那行代码,我仍然会得到同样的错误。在错误中,它引用了种子文件的第23行,这是Flight.create操作的开始。它以前确实试图创建flight_id,但现在已经改为flight_number,我已经保存了文件,并彻底重新启动了计算机。

这是flights_controller.rb文件:

class FlightsController < ApplicationController
before_action :set_flight
def index
@flight = Flight.all
end
def new
@flight = Flight.new
end
def create
@flight = Flight.new(flight_params)
end
private
def set_flight
@flight = Flight.find(params[:id])
end
def flight_params
params.require(:flight).permit(
:airport,
:flight_number,
:origin,
:origin_id,
:destination_id,
:destination,
:duration,
:departure_time,
:arrival_time
)
end
end

我以前将flight_id作为允许的参数,但现在已更改为flight_number。

所以,我有点不知所措,不知道下一步该做什么。如有任何帮助,我们将不胜感激。我很乐意提供您可能认为相关的任何其他信息。非常感谢。

Edit补充道,我试图从rails控制台创建一个表条目,但在irb中得到了相同的错误。

irb(main):001:0>Flight.create!(出发时间:"2022-12-25 11:11:11-0700";,持续时间:200,航班编号:1599,始发地id:Airport.first,目的地id:机场.flast)机场负荷(0.2ms)选择"机场"。*FROM";机场";ORDER BY";机场"id";ASC限制$1[["LIMIT",1]]机场负荷(0.1ms)SELECT";机场"。*来自"机场";ORDER BY";机场"id";DESC LIMIT$1[["LIMIT",1]]
/home/stuart/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/attribute.rb:211:inwith_value_from_database': can't write unknown attribute航班_id`(ActiveModel::MissingAttributeError)

raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"                                          
^^^^^                                                                                                                                                                                               irb(main):002:0>

问题是您已经定义了与foreign_key: "flight_id"的关联

class Flight < ApplicationRecord
belongs_to :booking, foreign_key: "flight_id"
end

此选项记录为:

指定用于存储关联对象的类型的列

不用说,使用引用bookingsflights.flight_id列是错误的。

让我们擦除这个中断的尝试,然后再试一次。让你在GIT和回滚中工作,并让你正确设置这些模型。

要设置航班、机场和航空公司之间的关联,您应该使用三个表并将它们关联起来,如下所示:

# rails g model airline name
class Airline < ApplicationRecord
has_many :flights
end
# rails g model airport name iata_code
class Airport < ApplicationRecord
has_many :flights_as_origin,
class_name: 'Flight',
foreign_key: :origin_id
has_many :flights_as_destination,
class_name: 'Flight',
foreign_key: :destination_id
end
# rails g model flight flight_number:string airline:references origin:references destination:references
class Flight < ApplicationRecord
belongs_to :airline
# These should be belongs_to assocations
belongs_to :origin, class_name: 'Airport'
belongs_to :destination, class_name: 'Airport'
end

这是所有乘客通用的数据。当乘客订票时,你不能在这里更改任何东西。在创建flights表时,您需要明确地告诉Railsdestination_idorigin_id应该指向airports表:

class CreateFlights < ActiveRecord::Migration[7.0]
def change
create_table :flights do |t|
# ...
t.references :origin, null: false, foreign_key: { to_table: :airports }
t.references :destination, null: false, foreign_key: { to_table: :airports }
# ...
end
end
end

为了模拟乘客、航班和预订之间的关联,您实际上想要一个带有联接表的多对多关联:

# rails g model ticket passenger_name:string flight:references seat:string
class Ticket < ApplicationRecord
belongs_to :flight
end 
class Booking < ApplicationRecord
belongs_to :user
has_many :tickets
has_many :flights, through: :tickets
end
class Flight < ApplicationRecord
# ...
has_many :tickets
has_many :bookings, through: :tickets
end

在这里,您可以使用票务表将每个项目存储在一个itenary中,这样您就可以实际模拟多段旅行和每次预订的多个乘客。

相关内容

最新更新