Ruby на рельсах | Как вставить новую строку в таблицу базы данных с тремя внешними ключами - PullRequest
0 голосов
/ 01 марта 2020

Я использую Ruby 2.6.3

У меня есть четыре таблицы:

Таблица № 1: транзакция (идентификатор, заголовок)

Таблица № 2: Поездка (идентификатор, имя)

Таблица № 3: TripBreakdown (идентификатор, имя)

Таблица № 4: TripTransaction (идентификатор, транзакция-идентификатор, trip_id, trip_breakdown_id)

Каждая транзакция может принадлежат к одной поездке и одной поездке. Одна поездка имеет много транзакций, а одна TripBreakdown имеет много транзакций, поэтому каждая транзакция относится к нулю или более Trip и TripBreakdown.

Для этого я создал Таблицу # 4 для хранения транзакции_id, trip_id и trip_breakdown_id

Я хочу создать таблицу TripTransaction так, чтобы (транзакция_id, trip_id, trip_breakdown_id) были всеми внешними ключами.

Вот как выглядят классы моделей:

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) Я не уверен, правильны ли мои классы моделей?

2) Как мне создать новый объект TripTransaction, связать его с тремя внешними ключами и вставить в базу данных?

Если у меня есть один внешний ключ, в документации говорится, что я могу сделать что-то вроде @book = @author.books.create(published_at: Time.now), но как я могу это сделать в моем случае? Спасибо

Ответы [ 2 ]

2 голосов
/ 01 марта 2020

Ответ 1: Вам не нужна таблица соединений (trip_transactions), так как транзакция имеет одну поездку и одну аварию поездки. Ваши транзакции таблицы будут иметь столбцы trip_id и trip_breakdown_id. Если они могут быть равны нулю, вы устанавливаете опционально:: 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
1 голос
/ 01 марта 2020

@ Catmal имеет право модели. Я бы добавил переименование родовой транзакции c в более конкретную c 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
)

Они создадут объект Transaction, связанный с Trip и TripBreakdown. Использование версии ! 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 :: Ассоциации :: ClassMethods .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...