在Rails 4中使用单个表单保存多个记录

Gee*_*ack 5 ruby-on-rails ruby-on-rails-4

我有一个名为Family的模型,其属于user. 我想让用户在单个表单中添加多个家庭成员,这位于/views/families/new.html.erb

编辑:对不起,我应该在稍微修改代码后提供更详细的代码

在routes.rb资源中:系列编辑:在User.rb中

class User < ActiveRecord::Base
  has_many :families
end
Run Code Online (Sandbox Code Playgroud)

编辑:在Family.rb

class Family < ActiveRecord::Base
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)

在FamiliesController中

def new

end
Run Code Online (Sandbox Code Playgroud)

编辑:我已经这样修改了表单:

<%= form_tag(controller: "families") do %>
<% i = 0 %>
<% 3.times do %>
<br>
<h2>Family Member #<%= i+1 %> : </h2>
<br>
<%= fields_for("family[#{i}]") do |f| %>
    <%= f.text_field :name, class: "form-control" , placeholder: "Name"%> <br>
    <%= f.text_field :relationship, class: "form-control" , placeholder: "Relationship" %> <br>
    <%= f.date_field :dob, class: "form-control" %> <br>
    <%= f.text_field :blood_group, class: "form-control", placeholder: "Blood group" %> <br>
    <%= f.text_field :email, class: "form-control", placeholder: "Email" %> <br>
    <%= f.number_field :phone, class: "form-control", placeholder: "Phone number" %> <br>
    <%= f.text_area :hobbies, class: "form-control", placeholder: "Hobbies" %> <br>
    <% i=i+1 %>
<% end %>
<hr>
<% end %> <br>
<%= submit_tag "Submit", class: "btn btn-primary" %> <br>
Run Code Online (Sandbox Code Playgroud)

编辑:在FamiliesController中创建动作

def create

        @family = Family.new(family_params)
        a = params[:family][:"0"]
        @family.user_id = current_user.id
        if @family.save
        flash[:notice] = params[:family][:"0"]

    redirect_to dummy_path
else
    flash[:notice] = "didnt happen"
end
end
Run Code Online (Sandbox Code Playgroud)
  • 因此,用户可以看到一个表单,用于为一个user_id创建3个系列成员
  • 将数据输入3个相同的表单,然后点击提交
  • 来自3个单独表单的数据应该仅在提交一次时保存为数据库中的3个不同记录

编辑:我正在使用强大的参数,如下所示:

def family_params
    params.require(:family).permit(:all)
end
Run Code Online (Sandbox Code Playgroud)
  • 现在,当我提交表单时,db中的所有值都保存为NULL.

  • 我究竟做错了什么?我不应该使用强力的参数吗?

win*_*yer 8

你想用nested forms.您应该能够复制并粘贴以下代码以开始:

应用程序/模型/ family.rb

class Family < ActiveRecord::Base
  has_many :users

  accepts_nested_attributes_for :users
end
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ user.rb

class User < ActiveRecord::Base
  belongs_to :family
end
Run Code Online (Sandbox Code Playgroud)

应用程序/视图/家庭/ new.html.erb

<%= form_for(@family) do |f| %>
  <%= f.fields_for :users do |user| %>
    <p>
    <%= user.text_field :name %><br>
    <%= user.text_field :email %>
    </p>
  <% end %>

  <%= f.submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/ families_controller.rb

  [...]

  def new
    @family = Family.new
    3.times { @family.users.build }
  end

  [...]

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_family
      @family = Family.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def family_params
      params.require(:family).permit(:name, users_attributes: [ :name, :email ])
    end
Run Code Online (Sandbox Code Playgroud)

  • 单个用户如何拥有多个家庭?我认为这个问题缺乏模型的代码. (2认同)

Pav*_*van 1

您需要像这样调整代码。假设您name在用户表中有该属性。

在您的用户模型中

class User < ActiveRecord::Base
  has_many :families, :dependent => :destroy 
  accepts_nested_attributes_for :families, :allow_destroy => true
end
Run Code Online (Sandbox Code Playgroud)

在你的 users_controller 中

def new
  @user = User.new
  @family = 3.times { @user.families.build } #here
end
Run Code Online (Sandbox Code Playgroud)

你的强参数应该是这样的

def user_params 
  params.require(:user).permit(:name, families_attributes: [:name,:email]) 
end

# users/new.html.erb
<%= form_for(@user) do |f| %>
  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>
  <%= f.fields_for :familes do |builder| %>
    <%= render 'family_fields', :f => builder %>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

# users/_family_fields.html.erb
<div>
  <%= f.label :name, "Name" %>        
  <%= f.text_field :name %>
  <br>
  <%= f.label :email, "Email" %>
  <%= f.text_field :email %>
</div>
Run Code Online (Sandbox Code Playgroud)