RoR: ассоциации между моделями

#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 , разве не должно быть наоборот?