#ruby-on-rails #ruby #ruby-on-rails-5
#ruby-on-rails #ruby #ruby-on-rails-5
Вопрос:
Я сделал миграцию между 2 моделями в качестве ссылки ( rails g migration AddAtendimentoToPacientes atendimento:references
).
В своих моделях я пытался использовать следующие методы для ассоциаций:
paciente.rb
class Paciente < ApplicationRecord
has_many(:atendimento)
end
atendimento.rb
class Atendimento < ApplicationRecord
belongs_to(:paciente)
end
Вывод на консоль Rails:
[1] pry(main)> paciente = Paciente.last
Paciente Load (0.1ms) SELECT "pacientes".* FROM "pacientes" ORDER BY "pacientes"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<Paciente:0x0000000009928a20
id: 2,
paciente_nome: "Maria Lucia",
paciente_cpf: "28123712283",
paciente_idade: 25,
created_at: Tue, 17 Nov 2020 03:30:58 UTC 00:00,
updated_at: Tue, 17 Nov 2020 03:30:58 UTC 00:00,
atendimento_id: nil>
[2] pry(main)> consulta = Atendimento.last
Atendimento Load (0.1ms) SELECT "atendimentos".* FROM "atendimentos" ORDER BY "atendimentos"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<Atendimento:0x000000000b4ef3a8
id: 2,
data_consulta: "22/12/2020",
tipo_consulta: "Microagulhamento",
valor_consulta: 1500.0,
is_pago: true,
profissional: "Rodrigo",
created_at: Tue, 17 Nov 2020 03:30:58 UTC 00:00,
updated_at: Tue, 17 Nov 2020 03:30:58 UTC 00:00>
[3] pry(main)> paciente.atendimento << consulta
(0.0ms) begin transaction
(0.0ms) rollback transaction
ActiveModel::MissingAttributeError: can't write unknown attribute `paciente_id`
from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/activemodel-5.2.4.4/lib/active_model/attribute.rb:207:in `with_value_from_database'
когда я пытаюсь:
paciente = Paciente.last
consulta = Atendimento.last
paciente.atendimento << consulta
Я хочу сообщить Rails, что Patient
модель может иметь несколько элементов (массив) внутри atendimento_id
, эти элементы будут собраны из Atendimento
модели / Atendimentos
таблицы
Миграция
class CreatePacientes < ActiveRecord::Migration[5.2]
def change
create_table :pacientes do |t|
t.string :paciente_nome
t.string :paciente_cpf
t.integer :paciente_idade
t.timestamps
end
end
end
class CreateAtendimentos < ActiveRecord::Migration[5.2]
def change
create_table :atendimentos do |t|
t.string :data_consulta
t.string :tipo_consulta
t.float :valor_consulta
t.boolean :is_pago
t.string :profissional
t.timestamps
end
end
end
class AddAtendimentoToPacientes < ActiveRecord::Migration[5.2]
def change
add_reference :pacientes, :atendimento, foreign_key: true
end
end
schema.rb
ActiveRecord::Schema.define(version: 2020_11_17_020521) do
create_table "atendimentos", force: :cascade do |t|
t.string "data_consulta"
t.string "tipo_consulta"
t.float "valor_consulta"
t.boolean "is_pago"
t.string "profissional"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "pacientes", force: :cascade do |t|
t.string "paciente_nome"
t.string "paciente_cpf"
t.integer "paciente_idade"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "atendimento_id"
t.index ["atendimento_id"], name: "index_pacientes_on_atendimento_id"
end
end
Комментарии:
1. Можете ли вы опубликовать созданный файл миграции? Вы его запускали?
2. @Matthew Сообщение отредактировано, добавлены миграции. Да, я выполнил миграцию с помощью db: migrate
Ответ №1:
В вашей модели вы можете установить связь «один ко многим», используя приведенный ниже синтаксис. Смотрите Руководство по Rails.
class Paciente < ApplicationRecord
has_many :atendimento
end
class Atendimento < ApplicationRecord
belongs_to :paciente
end
При добавлении внешнего ключа между одной и многими таблицами именно таблица has_many (:atendimento) будет хранить идентификатор (Paciente). Практически вам нужно откатить миграцию rails db rollback
и изменить файл миграции на синтаксис, приведенный ниже. Подробнее о внешних ключах читайте здесь .
class AddPacienteToAtendimentos < ActiveRecord::Migration[5.2]
def change
add_reference :atendimentos, :paciente, foreign_key: true
end
end
Комментарии:
1. Это работает, спасибо! Но я не могу понять теоретическую логику названия миграции (
AddPacienteToAtendimentos
), зачем добавлятьPaciente
Atendimentos
, разве не должно быть наоборот?