Allen
Allen

Reputation: 79

Rails - Nest Attributes Issues

I am having issues understanding this.

What am I trying to accomplish?

Problem

Any help would be appreciated.

Thanks in advance!

Form Code

<%= form_for(@inventory, html: {class: "form-horizontal"}) do |f| %>
  <% if @inventory.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@inventory.errors.count, "error") %> prohibited this inventory from being saved:</h2>

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

  <div class="form-group">
    <%= f.label :tablet_id, "Tablet #", class: "col-md-2 control-label" %>
    <div class="col-md-4">
      <%= select("inventory", "tablet_id", Tablet.where("status = '1'").all.collect{ |t| [t.alias, t.id] }, {}, { class: "form-control"} ) %>
    </div>
  </div>

  <%= f.fields_for :tablet do |t| %>
    <%= t.hidden_field :status, value: 2 %>
  <% end %>

  <div class="form-group">
    <%= f.label :chauffeur_id, "Chauffeur #", class: "col-md-2 control-label" %>
    <div class="col-md-4">
      <%= select("inventory", "chauffeur_id", Chauffeur.where("status = '1'").all.collect{ |t| [t.chaufNum, t.id] }, {}, { class: "form-control"} ) %>
    </div>
  </div>

  <%= f.fields_for :chauffeur do |t| %>
    <%= t.hidden_field :status, value: 2 %>
  <% end %>

  <div class="form-group">
    <%= f.label :vehicle_id, "Vehicle #", class: "col-md-2 control-label" %>
    <div class="col-md-4">
      <%= select("inventory", "vehicle_id", Vehicle.where("status = '1'").all.collect{ |t| [t.vehNum, t.id] }, {}, { class: "form-control"} ) %>
    </div>
  </div>

  <%= f.fields_for :vehicle do |t| %>
    <%= t.hidden_field :status, value: 2 %>
  <% end %>

  <div class="form-group">
    <div class="col-md-2 col-md-offset-2">
      <%= f.submit class: "btn btn-sm btn-success" %>
    </div>
  </div>
<% end %>

Model (Inventory)

class Inventory < ActiveRecord::Base
  belongs_to :tablet
  belongs_to :chauffeur
  belongs_to :vehicle

  accepts_nested_attributes_for :tablet
  accepts_nested_attributes_for :chauffeur
  accepts_nested_attributes_for :vehicle

  has_paper_trail

  validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
  validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }

end

Inventory Controller

class InventoriesController < ApplicationController
  before_action :authenticate_user!
  before_filter :set_paper_trail_whodunnit
  before_action :set_inventory, only: [:show, :edit, :update, :destroy]

  # GET /inventories
  # GET /inventories.json
  def index
    @inventories = Inventory.all.paginate(:page => params[:page], :per_page => 15)
  end

  # GET /inventories/1
  # GET /inventories/1.json
  def show
    @versions = PaperTrail::Version.order('created_at DESC')
  end

  # GET /inventories/new
  def new
    @inventory = Inventory.new
  end

  # GET /inventories/1/edit
  def edit
  end

  def history
    @versions = PaperTrail::Version.order('created_at DESC')
  end

  # POST /inventories
  # POST /inventories.json
  def create

    # @inventory = Inventory.new(inventory_params)

    render plain: params[:inventory].inspect

    # respond_to do |format|
    #   if @inventory.save
    #     format.html { redirect_to @inventory, notice: 'Inventory was successfully created.' }
    #     format.json { render :show, status: :created, location: @inventory }
    #   else
    #     format.html { render :new }
    #     format.json { render json: @inventory.errors, status: :unprocessable_entity }
    #   end
    # end
  end

  # PATCH/PUT /inventories/1
  # PATCH/PUT /inventories/1.json
  def update
    respond_to do |format|
      if @inventory.update(inventory_params)
        format.html { redirect_to @inventory, notice: 'Inventory was successfully updated.' }
        format.json { render :show, status: :ok, location: @inventory }
      else
        format.html { render :edit }
        format.json { render json: @inventory.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /inventories/1
  # DELETE /inventories/1.json
  def destroy
    @inventory.destroy
    respond_to do |format|
      format.html { redirect_to inventories_url, notice: 'Inventory was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_inventory
      @inventory = Inventory.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def inventory_params
      params.require(:inventory).permit(:tablet_id, :chauffeur_id, :vehicle_id, tablet_attributes: [:status => '2'], chauffeur_attributes: [:status => '2'], vehicle_attributes: [:status => '2'])
    end

end

Upvotes: 1

Views: 47

Answers (1)

Rodrigo Martinez
Rodrigo Martinez

Reputation: 711

Clean all your nested attribute code. This is not what you want. So model like this:

class Inventory < ActiveRecord::Base
  belongs_to :tablet
  belongs_to :chauffeur
  belongs_to :vehicle

  has_paper_trail

  validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
  validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }
end

Now, what you want to use a rails callback so that when you create an inventory then you update the status of other things. This goes on your model too:

class Inventory < ActiveRecord::Base
  ...

  after_create :update_status

  protected

    def update_status
      self.tablet.update_attribute(:status, 2)
      self.chauffeur.update_attribute(:status, 2)
      self.vehicle.update_attribute(:status, 2)
    end
end

Also remember to clean all your fields_for code and your strong parameters on your controller...you don't need the nested ones anymore.

Upvotes: 2

Related Questions