【问题标题】:How to use fields_for to link multiple models from one form?如何使用 fields_for 从一个表单链接多个模型?
【发布时间】:2019-01-17 03:47:36
【问题描述】:

我正在构建一个注册应用程序。共有三种型号:ParticipantVolunteer_DetailStudent_DetailParticipant 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 而不是@participant.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 %>

这是我的参与者控制器:

类 ParticipantsController

            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)

看看是否有人可以帮助澄清我的错误。

谢谢!

【问题讨论】:

    标签: ruby-on-rails activeadmin belongs-to nomethoderror has-one


    【解决方案1】:

    有几件事可能会有所帮助

    1. 如何定义has_one关系

      按照rails guide,既然Participant有_一个student_detail,那么student_detail表必须有participant_id字段,volunteer_detail也必须有participant_id字段

      你可以设置participant.rb(模型)接受student_detail或volunteer_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. 如何为其他表设置 participant_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 学习,虽然它看起来很老,但您可以学习这个概念

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      相关资源
      最近更新 更多