Today I Learned

A Hashrocket project

Rails nested forms

You can use rails Nested Forms even with plain form objects.

You just need to use form.fields_for and then declare the params name and the object for validation errors.

view

= form_for @foo_form, as: :foo, url: foo_path do |form|
  = form.text_field :name
  = form.fields_for :bar_params, @foo.bar do |nested_form|
    = nested_form.text_field :description

form

class FooForm
  include ActiveModel::Model

  attr_accessor :name, :bar_params, :bar
  validates :name, presence: true

  def initialize(attributes = {})
    super attributes

    self.bar  = BarForm.new(bar_params)
  end

  def save
    valid? && Foo.create(name: name)&& bar.save
  end
end
class BarForm
  include ActiveModel::Model

  attr_accessor :description
  validates :description, presence: true

  def save
    valid? && Bar.create(description: description)
  end
end

controller

class FooController < ApplicationController
  def edit
    @foo_form = FooForm.new
  end

  def create
    @foo_form = FooForm.new(params[:foo])
    if @foo_form.save
      redirect_to root_path
    else
      render :edit
    end
end

So the bar params will be scoped into bar_params node, and the validations will work.

Looking for help? Hashrocket has been an industry leader in Ruby on Rails since 2008. Rails is a core skill for each developer at Hashrocket, and we'd love to take a look at your project. Contact us and find out how we can help you.