Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Created November 1, 2011 23:40
Show Gist options
  • Save stevenharman/1332290 to your computer and use it in GitHub Desktop.
Save stevenharman/1332290 to your computer and use it in GitHub Desktop.
Proof of Concept: create multiple, identical, AR models from a single form.
<div>
<h1>Add a thing to your box</h1>
<%= form_for @thing, html: { class: "form-stacked" } do |f| %>
<label>Name: <%= f.collection_select :widget_id, @widgets, :id, :name,
{include_blank: true}, autofocus: true %></label>
<label>Blah: <%= f.text_field :blah %></label>
<label>Other stuff: <%= f.text_field :other %></label>
<label>Count: <%= text_field_tag :count, @thing_count %></label>
<%= f.submit "Add them!" %>
<% end %>
</div>
class ThingController < ApplicationController
def new
@thing = Thing.new
@thing_count = 1
@widgets = Widget.all
end
def create
@thing_count = params[:count].to_i
widget = Widget.find_by_id(params[:thing][:widget_id])
new_things = (0...@thing_count).collect do |i|
Thing.create(params[:thing]) { |t| t.widget = widget }
end
if new_things.all?(&:valid?)
redirect_to(things_path, notice: "Things with #{widget.name} have been added to the box!")
elsif
@thing = new_things.find(&:invalid?)
@widgets = Widget.all
flash.now[:alert] = "Oops! #{@thing.errors.full_messages.join(", ")}"
new_things.map { |t| t.delete }
render :new
end
end
end
@stevenharman
Copy link
Author

What about the following API?

# things_controller.rb
def create
  @thing_count = params[:count].to_i
  adds_things = AddsThingsToBox.new
  adds_things.add(@thing_count, params[:thing])

  if adds_things.success?
    redirect_to(things_path, notice: "Things with #{adds_things.widget.name} have been added to the box!")
  else
    @thing = adds_things.invalid_thing
    @widgets = Widget.all
    flash.now[:alert] = "Oops! #{@thing.errors.full_messages.join(", ")}"

    render :new
  end
end

Where most of the gunk of knowing how many Things to create, how to build them, and how to roll them back, is pushed off into the AddsThingsToBox object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment