Muhammad Ans
Muhammad Ans

Reputation: 179

Save multiple records using form_with in one go using nested approach

I am working on a Project where there as two models, (User,Project). They have many to many relationship and is implemented by has_many through which is (UserProject). I want the functionality that when I am creating a project, below projects models fields, all the db users should be listed below having checkbox in front of each. When user enters all the projects model fields and checks the checkboxes for example 2 checkboxes below(2 users), All the data should be saved which includes projects creation as well as two records of UserProject. Is there any way of doing this.. I am using form_with helper. User(id,email,password) Project(id,name) UserProject(id,user_id,project_id)

Upvotes: 0

Views: 128

Answers (1)

Jad
Jad

Reputation: 1286

If I'm understanding correctly, you want a form with sub-objects in it and a single submit.

I have done this in the past by #building the empty objects, so that they can be displayed in the form, and then handling them "correctly" in the params section:

Controller:

class MeetTypesController < ApplicationController

  def new
    @meet_type = MeetType.new

    Job.all.each do |job|
      @meet_type.meet_type_jobs.build(job: job, count: 0)
    end
    @meet_type.meet_type_jobs.sort_by{ |mtj| mtj.job.name }
  end

  def create
    @meet_type = MeetType.new(meet_type_params)

    if @meet_type.save
      redirect_to meet_types_path
    else
      render 'new'
    end
  end

  def edit
    (Job.all - @meet_type.jobs).each do |job|
      @meet_type.meet_type_jobs.build(job: job, count: 0)
    end
    @meet_type.meet_type_jobs.sort_by{ |mtj| mtj.job.name }
  end

  def update
    if @meet_type.update(meet_type_params)
      redirect_to meet_types_path
    else
      render 'edit'
    end
  end

  def show; end

  def index
    @meet_types = MeetType.in_order
  end

  private

  def meet_type_params
    params.require(:meet_type).permit(:name, meet_type_jobs_attributes: [:id, :job_id, :count])
  end
end

view:

%h1 Editing Meet Type
= bootstrap_form_for(@meet_type, layout: :horizontal) do |f|
  = f.text_field :name, autocomplete: :off
  %h2 Count of Jobs
  = f.fields_for :meet_type_jobs do |jf|
    = jf.hidden_field :job_id
    = jf.number_field :count, label: jf.object.job.name, step: 1, in: 0..5
  = f.form_group do
    = f.primary
%para
= errors_for @meet_type

I hope this helps.

Upvotes: 0

Related Questions