Rails多对多:通过关联嵌套表单

时间:2015-08-03 09:45:36

标签: ruby-on-rails ruby rails-activerecord

在我的rails项目中,我有三个模型:

class Subject < ActiveRecord::Base
  has_many :enrolments
  has_many :users, through: :enrolments , :foreign_key => :user_id
  accepts_nested_attributes_for :enrolments

class User < ActiveRecord::Base
  has_many :enrolments
  has_many :subjects, through: :enrolments , :foreign_key => :subject_id
  accepts_nested_attributes_for :enrolments

class Enrolment < ActiveRecord::Base
  belongs_to :user
  belongs_to :subject
  accepts_nested_attributes_for :user

subjects_controller.rb

 class SubjectsController < ApplicationController
    def new
    @subject = Subject.new
    @user = User.find(params[:id])
    @subject.enrolments.build(:user_id => @user.id)
  end


  def create
    @subject= Subject.create(subject_params)
    respond_to do |format|
      if @subject.save
        format.html { redirect_to @subject, notice: 'Subject was successfully created.' }
        format.json { render :show, status: :created, location: @subject }
      else
        format.html { render :new }
        format.json { render json: @subject.errors, status: :unprocessable_entity }
      end
    end

 def subject_params
     params.require(:subject).permit(:name,
     enrolments_attributes: [ :user_id, :subject_id, :_destroy, user_attributes: [ :id, :email,  :_destroy]]
    )
 end
end

查看(用于测试,将使用cocoon插入多个用户):

<div class="container" style="padding-left: 0px;">
  <div class="col-md-9">
    <p id="notice"><%= notice %></p>
  <%= form_for @subject, html: {class: "form-horizontal"} do |f| %>
  <fieldset id="recipe-meta">
    <ol>
      <li class="control-group">
        <%= f.label :name, "Subject name", class: "control-label" %>
        <div class="controls"><%= f.text_field :name %></div>
      </li>
    </ol>
  </fieldset>

  <fieldset>
      <%= f.fields_for :enrolments do |enrolment| %>
        <%= enrolment.hidden_field :subject_id %>
    <%= enrolment.fields_for :user , User.new do |enrolment_user| %>
     <%= enrolment_user.label :email %>
      <%= enrolment_user.text_field :email %>
    <% end %>
     <% end %>
  </fieldset>

  <%= f.submit %>
<% end %>

  </div>
</div>

意图:同时创建主题为学生手动注册多个字段(电子邮件)的用户帐户,然后将多个user_id插入到注册表中。

示例注册表:

id   user_id    subject_id
--------------------------------------
1     2           1   
2     3           1  
3     4           1  

更新(代码现在有效):

  

@subject.enrolment.build添加到SubjectController def new方法

2 个答案:

答案 0 :(得分:0)

您已将用户添加到嵌套表单,但忘记将其添加到控制器参数白名单中。确保在SubjectsController中的subject_params方法中正确定义了用户。

根据我的评论:

@JackGoh:您的subject_params错误,但与您的电子邮件字段无关。可能会修复未显示@ subject.enrolments.build的电子邮件(用户:@user)。

答案 1 :(得分:0)

控制器中的嵌套与视图和模型中指定的嵌套不同。也许试试这个:

params.require(:subject).permit(
  :name,
  enrolments_attributes: [
    :user_id, :subject_id, :_destroy, 
    user_attributes: [:id, :email,  :_destroy]
  ]
)

另外,我建议重写&#34;注册&#34;的模型,视图和控制器。 as&#34;注册&#34;。