Как использовать fields_for для связывания нескольких моделей из одной формы? - PullRequest
0 голосов
/ 17 января 2019

Я создаю регистрационное приложение. Существует три модели: Participant, Volunteer_Detail и Student_Detail. Participant has_one двух других моделей, в то время как они в свою очередь belongs_to Participant. Я пытаюсь использовать одну форму с fields_for для предоставления данных для Participant и одной из других моделей.

Я продолжаю получать сообщение о том, что один из атрибутов, предназначенных для Student_Detail, не является определенным атрибутом Participant.

Я посмотрел несколько руководств по fields_for, и кажется, что есть несколько способов определить вторую модель, для которой предназначена ваша форма.

Похоже, что консенсус выглядит так:

         <%= f.fields_for @participant.student_details do |student_detail_field| %>
                    <%= f.label :nationality, 'Nationality:' %> 
                    <%= student_detail_field.text_field :nationality %>

Однако, похоже, моя форма отображается только тогда, когда я пишу: student_details, а не @ Particip.student_details.

Вот моя форма, показывающая верхнюю секцию и секцию, в которую входят fields_for (форма обрезается для экономии места):

                    <%= f.label :first_name, 'First:' %>
                    <%= f.text_field :first_name %>

         <%= f.fields_for :student_details do |student_detail_field| %>
                    <%= f.label :nationality, 'Nationality:' %> 
                    <%= student_detail_field.text_field :nationality %>

Вот мой контроллер участников:

класс УчастникиКонтроллер

            def new2
            @participant= Participant.new
            end

            def create
            @participant = Participant.create(participant_params)
            @participant.save
            if @participant.save
            flash[:success] = "Successfully Registered!"        

            #email notifes admin of new registration
            NotifyMailer.notify_email(@participant).deliver_later

            redirect_to '/signup'
            end
            end

            def edit
            end

            def update
            end

            def show
            end

            def index
            end

            private
            def participant_params
            params.require(:participant).permit(:first_name, :last_name, :gender, :email, :birthdate, :phone, :street_name, :city, :state, :zip, :nationality, :religion, :need_ride, 
            :has_spouse, :spouse_name, :english_level, :expectations, :length_of_stay, :exact_length, :volunteer_id, :matched, :returned_home, :participant_id, :participant_id_id)

            end


            end

Вот ошибка сервера:

    NoMethodError (undefined method `nationality' for #<Participant:0x000000000d039410>
                            Did you mean?  Rational):

                            app/controllers/participants_controller.rb:11:in `create'
                            Rendering C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
                            Rendering C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
                            Rendered C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (3.9ms)
                            Rendering C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
                            Rendered C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.0ms)
                            Rendering C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
                            Rendered C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
                            Rendered C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/actionpack-5.0.7.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (790.6ms)

Нужно выяснить, может ли кто-нибудь помочь уточнить, что я делаю неправильно.

Спасибо!

1 Ответ

0 голосов
/ 17 января 2019

Есть пара вещей, которые могут помочь

  1. Как определить отношение has_one :

    В соответствии с руководством по рельсам , так как у участника имеется_одно ученик_детали, то в таблице student_detail должно быть поле member_id, также поле волонтера_детали должно иметь поле member_id

    вы можете установить participant.rb (модель), чтобы принимать вложенные атрибуты для student_detail или волонтера_детали (так как вы сказали, предоставьте одну форму для этих таблиц)

    class Participant < ActiveRecord::Base
      has_one :student_detail, :dependent => :destroy
      accepts_nested_attributes_for :student_detail,   :allow_destroy => :true
      # that allow_destroy is depend with your software design
      has_one :volunteer_detail, :dependent => :destroy
      accepts_nested_attributes_for :volunteer_detail,   :allow_destroy => :true
    end
    
  2. Как настроить member_params для других таблиц:

    Вот пример кода, который определяет параметры участника для принятия вложенных атрибутов:

    def participant_params
      params.require(:participant).permit(
        :first_name, :other_participant_field_name, 
        student_detail_attributes: [:participant_id, :other_student_field_name],
        volunteer_detail_attributes: [:participant_id, :other_volunteer_field_name])
      end
    end
    

    Если вы хотите, чтобы содержимое для записи студента также для volunteer_detail вы могли сделать в своем контроллере (метод создания), мой совет для этой попытки попытаться реорганизовать / изменить дизайн, чтобы минимизировать дублирование данных в вашей системе (студент и волонтер) )

    def create
      @participant = Participant.create(participant_params)
      @volunteer_detail = @participant.student_detail
      # this will pass all the content of student detail to volunteer detail
      if @participant.save
        flash[:success] = "Successfully Registered!"        
      end
    end
    

Чтобы узнать больше о принятии вложенных атрибутов, я предлагаю вам узнать из railcast 196 , хотя это кажется старым, но вы можете изучить концепцию

...