ruby on rails - references - Rails has_many: a través de forma anidada
rails references (3)
"Lo tengo funcionando. Acabo de cambiar los modelos de la siguiente manera": citado por Shruti en los comentarios anteriores
class Patient < ActiveRecord::Base
has_many :appointments, :dependent => :destroy
has_many :physicians, :through => :appointments
accepts_nested_attributes_for :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
accepts_nested_attributes_for :physician
end
Acabo de saltar a has_many :through
asociación. Estoy tratando de implementar la capacidad de guardar datos para las 3 tablas ( Physician
, Patient
y tabla de asociación) a través de un solo formulario.
Mis migraciones:
class CreatePhysicians < ActiveRecord::Migration
def self.up
create_table :physicians do |t|
t.string :name
t.timestamps
end
end
end
class CreatePatients < ActiveRecord::Migration
def self.up
create_table :patients do |t|
t.string :name
t.timestamps
end
end
end
class CreateAppointments < ActiveRecord::Migration
def self.up
create_table :appointments do |t|
t.integer :physician_id
t.integer :patient_id
t.date :appointment_date
t.timestamps
end
end
end
Mis modelos:
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
accepts_nested_attributes_for :appointments
accepts_nested_attributes_for :physicians
end
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
accepts_nested_attributes_for :patients
accepts_nested_attributes_for :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
Mi controlador
def new
@patient = Patient.new
@patient.physicians.build
@patient.appointments.build
end
Mi vista ( new.html.rb
):
<% form_for(@patient) do |patient_form| %>
<%= patient_form.error_messages %>
<p>
<%= patient_form.label :name, "Patient Name" %>
<%= patient_form.text_field :name %>
</p>
<% patient_form.fields_for :physicians do |physician_form| %>
<p>
<%= physician_form.label :name, "Physician Name" %>
<%= physician_form.text_field :name %>
</p>
<% end %>
<p>
<%= patient_form.submit ''Create'' %>
</p>
<% end %>
<%= link_to ''Back'', patients_path %>
Puedo crear un nuevo registro de Patient
, Physician
y asociado para una Appointment
, pero ahora quiero tener el campo para appointment_date
también en forma. ¿Dónde debo colocar los campos para las Appointment
y qué cambios se requieren en mi controlador? Intenté googlear y probé this , pero me quedé atascado en algún error u otro implementándolo.
Ok, esta pequeña pregunta me dejó perplejo durante algunas horas, por lo que voy a publicar mi solución de trabajo aquí con la esperanza de que tenga tiempo para las personas. Esto es para Rails 4.0 y Ruby 2.0. Esto también superó un problema de "conversión de símbolos a enteros" que tenía.
Modelos:
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through: :appointments
accepts_nested_attributes_for :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
accepts_nested_attributes_for :physician
end
class Physicians < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
Controlador:
def new
@patient= Patient.new
@appointments = @patient.appointments.build
@physician = @appointments.build_physician
end
def create
Patient.new(patient_params)
end
def patient_params
params.require(:patient).permit(:id, appointments_attributes: [:id, :appointment_time, physician_attributes: [:id ] )
end
Ver
<% form_for(@patient) do |patient_form| %>
<%= patient_form.error_messages %>
<p>
<%= patient_form.label :name, "Patient Name" %>
<%= patient_form.text_field :name %>
</p>
<% patient_form.fields_for :appointments do |appointment_form| %>
<p>
<%= appointment_form.label :appointment_date, "Appointment Date" %>
<%= appointment_form.date_field :appointment_date %>
</p>
<% appointment_form.fields_for :physician do |physician_form| %>
<p>
<%= physician_form.label :name, "Physician Name" %>
<%= physician_form.text_field :name %>
</p>
<% end %>
<% end %>
<p>
<%= patient_form.submit ''Create'' %>
</p>
<% end %>
<%= link_to ''Back'', patients_path %>
Su clase de pacientes acepta atributos anidados tanto para médicos como para citas. Intente agregar otro método fields_for
para la cita.
<% form_for(@patient) do |patient_form| %>
<%= patient_form.error_messages %>
<p>
<%= patient_form.label :name, "Patient Name" %>
<%= patient_form.text_field :name %>
</p>
<% patient_form.fields_for :physicians do |physician_form| %>
<p>
<%= physician_form.label :name, "Physician Name" %>
<%= physician_form.text_field :name %>
</p>
<% end %>
<% patient_form.fields_for :appointments do |appointment_form| %>
<p>
<%= appointment_form.label :appointment_date, "Appointment Date" %>
<%= appointment_form.date_field :appointment_date %>
</p>
<% end %>
<p>
<%= patient_form.submit ''Create'' %>
</p>
<% end %>
<%= link_to ''Back'', patients_path %>