Problem with nested form has_many through using dynamic form

Asked

Viewed 330 times

0

I have the following problem in a form using has_many through.

I have a register where I created dynamic forms. These dynamic forms are inserted in another screen.

I’m having difficulty in the controller where I insert these pictures and the view I insert.

Appointments -> where I can have a lot of dynamic formulas (record_forms) Record_forms -> dynamic forms registration Record_form_fields -> dynamic form fields Appointment_record_forms -> Relationship table between Appointments and Record_forms

Schema

create_table "appointment_record_forms", force: :cascade do |t|
    t.integer  "appointment_id", limit: 4
    t.integer  "record_form_id", limit: 4
    t.datetime "created_at",                   null: false
    t.datetime "updated_at",                   null: false
    t.text     "properties",     limit: 65535
  end

  create_table "appointments", force: :cascade do |t|
    t.string   "duration",         limit: 255
    t.date     "appointment_date"
    t.integer  "patient_id",       limit: 4
    t.integer  "doctor_id",        limit: 4
    t.datetime "created_at",                   null: false
    t.datetime "updated_at",                   null: false
  end

  create_table "record_form_fields", force: :cascade do |t|
    t.string   "name",           limit: 255
    t.string   "field_type",     limit: 255
    t.boolean  "required"
    t.integer  "record_form_id", limit: 4
    t.datetime "created_at",                 null: false
    t.datetime "updated_at",                 null: false
  end

  create_table "record_forms", force: :cascade do |t|
    t.string   "name",       limit: 255
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
  end

Models

class Appointment < ActiveRecord::Base
  belongs_to :patient
  belongs_to :doctor

  has_many   :appointment_record_forms, dependent: :destroy
  has_many   :record_forms, through: :appointment_record_forms
  has_many :record_form_fields

  accepts_nested_attributes_for  :appointment_record_forms, allow_destroy: true
 end

class AppointmentRecordForm < ActiveRecord::Base
  belongs_to :appointment
  belongs_to :record_form

  serialize :properties, Hash

  def validate_properties
    record_form.record_form_fields.each do |record_form_field|
      if record_form_field.required? && properties[record_form_field.name].blank?
        errors.add record_form_field.name, "must not be blank"
      end
    end
  end
end

class RecordForm < ActiveRecord::Base
    has_many :record_form_fields

    has_many :appointment_record_forms, dependent: :destroy
    has_many :appointments, through: :appointment_record_forms

    accepts_nested_attributes_for :record_form_fields, allow_destroy: true

end

class RecordFormField < ActiveRecord::Base
  belongs_to :record_form
end

**Controller**


class AppointmentsController < ApplicationController

.
.
.
def appointment_params
      params.require(:appointment).permit(:duration, :appointment_date, :patient_id, :doctor_id,
                                           :record_form_ids, :appointment_form_ids
          )
    end
end

View

Appointments/_form.html.erb

<!-- onde escolho um formulario dinamico e clico para inseri-lo -->

...
<%= f.fields_for :appointment_record_forms do |builder| %>
    <%= f.select_tag :record_form_id, options_from_collection_for_select(RecordForm.all, :id, :name) %>
    <%= render 'appointment_record_form_fields', f: builder %>
  <% end %>
  <%= link_to_add_fields "Add Field", f, :appointment_record_forms %>
....

Partial

Appointments/_appointment_record_form_fields.html.br

<!-- Aqui é onde eu carrego os campos do formulario dinamico e salvo e busco os valores desses campos atraves do hash 'properties' --> 

 <fieldset>  
  <%= f.fields_for :properties, OpenStruct.new(@appointment_record_forms.properties) do    |builder| %>
    <% @appointment_record_forms.record_form.record_form_fields.each do |record_form_field| %>

      <%= render "appointments/fields/#{record_form_field.field_type}", record_form_field: record_form_field, f: builder %>
    <% end %>
  <% end %>

  <%= f.hidden_field :_destroy %>
  <%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>

Currently running the application this with the error:

undefined method `properties' for :appointment_record_forms:Symbol

I would like to know how I should do in the appointment controller to receive the association, in the view to insert the dynamic form and Partial to list save the record in the hash and show the form fields correctly.

From now on I appreciate if anyone can help.

1 answer

1

first

class RecordForm < ActiveRecord::Base
    has_many :record_form_fields

    has_many :appointment_record_forms, dependent: :destroy
    has_many :appointments, through: :appointment_record_forms

    accepts_nested_attributes_for :record_form_fields, allow_destroy: true

you do accepts_nested from record_form_fields and not appointment_record_forms

end

according to

<%= f.fields_for :appointment_record_forms do |builder| %>

you call for appointment_record_forms without having accepts_nested

    <%= f.select_tag :record_form_id, options_from_collection_for_select(RecordForm.all, :id, :name) %>

    <%= render 'appointment_record_form_fields', f: builder %>

    <% end %>
    <%= link_to_add_fields "Add Field", f, :appointment_record_forms %>
....

I don’t think Serializing the hash should be instantiating that way. I do something like this bass

= form_for @widget do |f|
  = f.fields_for :options, OpenStruct.new(f.object.options || {}) do |f2|
    = f2.text_field :axis_y
    = f2.text_field :axis_x
    = f2.text_field :unit

https://stackoverflow.com/questions/1002963/how-to-edit-a-rails-serialized-field-in-a-form

What you got in here? @appointment_record_forms.properties

third and most importantly, start at baby-Steps.

View first /_appointment_record_form_fields.html.br run without these nested form all. Comment all the rest leaving the renders or put this down on views/appoiment..../new without the rest of Forms and fields_for

<%= form_for AppointmentRecordForm.new do |f| %>
   <%= f.fields_for :properties, OpenStruct.new(AppointmentRecordForm.new.properties || {} ) do    |ff| %>
     <%= ff.text_field :coluna_do_properties_1 %>
     <%= ff.text_field :coluna_do_properties_2 %>
    <% end %>
  <% end %>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.