All threads / Saving _form along with has_many through items

Ask A Question

Notifications

You’re not receiving notifications from this thread.

Saving _form along with has_many through items

Michael Stitt asked in General

Hi Chris,

I'm having difficulty wrapping my head around how to save a form (Kit) that includes optional items for a has_many through relationship (AmazonProductKit). Here are my models:

class Kit < ActiveRecord::Base
  has_many :amazon_product_kits
  has_many :amazon_products, through: :amazon_product_kits
end

class AmazonProduct < ActiveRecord::Base
  has_many :amazon_product_kits
  has_many :kits, through: :amazon_product_kits
end

class AmazonProductKit < ActiveRecord::Base
  belongs_to :kit
  belongs_to :amazon_product

  validates :quantity, presence: true
end

What I'd like to do with the Kits#_form is capture a couple Kit attributes (title, persons, and description) and then also allow the user to pick any AmazonProduct objects they'd like included in that Kit (this is how the form functions now, however, when I save it there are no AmazonProductKit objects being stored). I'd also like to have the ability to capture the quantity for each checked AmazonProductKit in a dropdown menu, but I haven't figured out how go about doing that.

So, I know I need to modify my controller and _form, I'm just not sure what exactly. Here's my kits_controller.rb:

class KitsController < ApplicationController
  before_action :set_kit, only: [:show]

  def index
    @kits = Kit.all
  end

  def show
  end

  def new
    @kit = Kit.new
  end

  def create
    @kit = Kit.create(kit_params)

    if @kit.save
      flash[:success] = "Kit has been created."
      redirect_to kit_path(@kit)
    else
      flash[:alert] = "Kit has not been created."
      render "new"
    end
  end

  private

    def set_kit
      @kit = Kit.find(params[:id])
    end

    def kit_params
      params.require(:kit).permit(:title, :persons, :description, :amazon_product_kits => [])
    end
end

And here's my kit _form.html.erb:

<%= form_for(@kit) do |f| %>
  <% if @kit.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@kit.errors.count, "error") %> prohibited this kit from being saved:</h2>

      <ul>
      <% @kit.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>


  <div class="field form-group">
    <%= f.label :title %><br>
    <%= f.text_field :title, required: true, autofocus: true, placeholder: "e.g. 72-hour Emergency Kit", class: "form-control" %>
  </div>
  <div class="field form-group">
    <%= f.label :persons %><br>
    <%= f.text_field :persons, autofocus: true, placeholder: "e.g. 1", class: "form-control" %>
  </div>
  <div class="field form-group">
    <%= f.label :description %><br>
    <%= f.text_area :description, rows: 10, autofocus: true, placeholder: "e.g. http://www.monkeysee.com/play/28716-orlando-s-newest-tourist-destination", class: "form-control" %>
  </div>

  <div class="field form-group">
    <%= collection_check_boxes(:kit, :amazon_product_kit_ids, AmazonProduct.all, :id, :title) do |b| %>
      <%= b.check_box %>
      <%= b.label %>
      <br>
      <!-- capture `quantity` of this AmazonProduct if checked -->
    <% end %>
  </div>


  <div class="actions form-group">
    <%= f.submit "Save Kit", class: "submit-button btn btn-default" %>
  </div>

<% end %>

Let me know if you think I should alter how I've constructed my model relationships or if I should consider tweaking how a new Kit is captured. Thanks in advance!

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 35,699+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.