我使用的是Ruby 2.6.3
我有四张桌子:
表1:交易(id,title(
表2:跳闸(id,name(
表3:TripBreakdown(id,name(
表4:TripTransaction(id,transaction_id,trip_id,trip_breakdown_id(
每个事务可以属于一个行程和一个行程细分。一个Trip有许多事务,一个TripBreakdown有很多事务因此,每个事务都属于零个或多个Trip和TripBreakdown。
为此,我创建了表#4来存储transaction_id、trip_id和trip_breakdown_id
我想创建TripTransaction表,以便(transaction_id、trip_id、trip_breakdown_id(都是外键。
这就是Model类的样子:
class Transaction < ApplicationRecord
belongs_to :trip_transaction, optional: true
end
class Trip < ApplicationRecord
has_many :trip_transactions, class_name: "TripTransaction", foreign_key: "trip_transaction_id"
end
class TripBreakdown < ApplicationRecord
has_many :trip_transactions, class_name: "TripTransaction", foreign_key: "trip_transaction_id"
end
class TripTransaction < ApplicationRecord
belongs_to :transactions, class_name: "Transaction", foreign_key: "transaction_id"
belongs_to :trips, class_name: "Trip", foreign_key: "trip_id"
belongs_to :trip_breakdowns, class_name: "TripBreakdown", foreign_key: "trip_breakdown_id"
end
问题:1( 我不确定我的Model类是否正确?
2( 如何创建新的TripTransaction对象,用三个外键连接它并将其插入数据库?
如果我有一个外键,文档上说我可以做@book = @author.books.create(published_at: Time.now)
之类的事情,但在我的情况下,我该怎么做呢?感谢
答案1:您不需要联接表(trip_transactions(,因为事务有一个行程和一个行程细分。您的表事务将具有列trip_id和trip_breakdown_id。若它们可以为零,则在关系中设置optional::true。
您可以简化为:
class Transaction < ApplicationRecord
belongs_to :trip, optional: :true
belongs_to :trip_breakdown, optional: :true
end
class Trip < ApplicationRecord
has_many :transactions
end
class TripBreakdown < ApplicationRecord
has_many :transactions
end
答案2:可以通过多种方式完成,具体取决于您创建记录的方式。给你一个想法的例子是:
@new_transaction = @trip.transactions.new
@new_transaction.trip_breakdown_id = @trip_breakdown.id
@new_transaction.save
@Catmal拥有正确的模型。我会将通用事务重命名为更具体的TripTransaction,并匹配其他相关的类名。
创作可以通过多种方式进行。这些都假设您已经拥有Trip和TripBreakdown对象。这些基本上都做着相同的事情,但也有细微的区别。
# Via Transaction.create!
transaction = Transaction.create!(
trip: trip,
trip_breakdown: trip_transaction
)
# Via Trip's transaction association.
transaction = trip.transactions.create!(
trip_breakdown: trip_transaction
)
# Via TripBreakdown's transaction association.
transaction = trip_breakdown.transactions.create!(
trip: trip
)
他们将创建一个与Trip和TripBreakdown关联的Transaction
对象。使用create的!
版本意味着如果出现问题,它们将引发异常,而不是静默地返回nil。
使用关联的优点是缓存的关联将被更新。例如,如果要使用Transaction.create!
,则可能会导致缓存过期。
# Load the Trip's transactions into memory
p trip.transactions
transaction = Transaction.create!(
trip: trip,
trip_breakdown: trip_transaction
)
# The Trip's transactions were cached. This will not include
# the new transaction.
p trip.transactions
# Now the new transaction is seen.
p trip.transactions.reload
如果您改为通过关联创建,则缓存的关联将被更新。
# Load the Trip's transactions into memory
p trip.transactions
# Create an associated Transaction and update the association.
trip.transactions.create!(
trip_breakdown: trip_transaction
)
# This will include the new Transaction.
p trip.transactions
有关详细信息,请参阅ActiveRecord::Associations::ClassMethods。