Saving multiple records with a single form in Rails 4

后端 未结 3 676
忘了有多久
忘了有多久 2020-12-30 14:23

I have a model called Family, which belongs_to User I want to enable the user to add multiple family members in a single form, which is in

相关标签:
3条回答
  • 2020-12-30 14:36

    You need to tweak your code like this.Assuming you have the attribute name in users table.

    In your User model

    class User < ActiveRecord::Base
        has_many :families, :dependent => :destroy 
        accepts_nested_attributes_for :families, :allow_destroy => true
    end
    

    In your users_controller

    def new
    @user = User.new
    @family = 3.times { @user.families.build } #here
    end
    

    Your strong parametrs should look like this

    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 %><br />
    <%= 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>
    
    0 讨论(0)
  • 2020-12-30 14:58

    You want to use nested forms. You should be able to copy and paste the following code to get going:

    app/models/family.rb

    class Family < ActiveRecord::Base
      has_many :users
    
      accepts_nested_attributes_for :users
    end
    

    app/models/user.rb

    class User < ActiveRecord::Base
      belongs_to :family
    end
    

    app/views/families/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 %>
    

    app/controllers/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
    
    0 讨论(0)
  • 2020-12-30 15:00

    The way that i always do this is to make a new action update_multiple. This expects params with the following structure (using your Family example, and updating two records, with ids 123 and 456)

    params = {:families => {123 => {:name => "foo", :address => "bar"}, 456 => {:name => "baz", :address => "qux"} }}
    

    and the action works like so:

    @families = []
    params[:families].each do |id, attributes|
      if family = Family.find_by_id(id)
        family.update_attributes(attributes)
        @families << family
      end
    end
    

    In order to set up the params with the required structure, your form would be set up like so:

    <% @families.each do |family| %>
      <div class="family">
        <label>Name: <%= text_field_tag "families[#{family_id}][name]", family.name %></label>
        <label>Address: <%= text_field_tag "families[#{family_id}][address]", family.address %></label>
      </div>
    <% end %>
    

    You could, instead of making a new action, change the structure of your update action to do the standard code if it gets params[:family] and the above code if it gets params[:families].

    0 讨论(0)
提交回复
热议问题