0

I have a nested attributes between:

class InventoryItem < ApplicationRecord
  belongs_to :location
  accepts_nested_attributes_for :location
end

class Location < ApplicationRecord
  has_many :inventory_items
  has_many :bins
  accepts_nested_attributes_for :bins
end

class Bin < ApplicationRecord
  belongs_to :location
end

The inventory_item form:

  <%= form.fields_for :location do |location| %>
    <div class="field">
      <%= location.label :location_name %>
      <%= location.text_field :name %>
    </div>
      <%= location.fields_for :bins do |bin| %>
        <div class="field">
          <%= bin.label :bin_name %>
          <%= bin.text_field :name %>
      </div>
      <% end %>
    </div>
  <% end %>

And in the inventory_item controller:

  def new
    @inventory_item = InventoryItem.new
    @inventory_item.build_location.bins.build
  end

  def inventory_item_params
    params.require(:inventory_item).permit(:location_id, location_attributes:[:name, bins_attributes:[:name]])
  end

The form:

enter image description here

My issue is that I can create an InventoryItem with a Location and Bin name blank and it creates a new Location and Bin and the corresponding association between InventoryItem and a blank Location. I want that when Location name or Bin name are blank in the form a new Location, a new Bin and the association will not be created.

Thanks in advance

John Fadria
  • 1,863
  • 2
  • 25
  • 31

1 Answers1

1

You can add a validation like this:

accepts_nested_attributes_for :location, reject_if: proc { |l| l[:name].blank? }

or you can also create a method in the InventoryItem model when to reject and call like this:

accepts_nested_attributes_for :location, reject_if: :reject_method?

def reject_method(attributes)
  attributes['name'].blank?
end

Read more about the syntax here: https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Deepesh
  • 6,138
  • 1
  • 24
  • 41
  • Thanks @deepesh, my problem now is that `Location must exist` – John Fadria Jul 16 '21 at 11:58
  • You can add `validates_presence_of :location` to check that on the `InventoryItem` model – Deepesh Jul 16 '21 at 12:01
  • Sorry @deepesh with this validation I optain two errors now. `Location must exist` and `Location can't be blank` If is blank I want to create the `InventoryItem` without a `Location` – John Fadria Jul 16 '21 at 12:05
  • `Location can't be blank` is from the validation we have added above, the `must exist` is from the `belongs_to` association. – Deepesh Jul 16 '21 at 12:07
  • https://stackoverflow.com/questions/38983666/validation-failed-class-must-exist – Deepesh Jul 16 '21 at 12:09
  • You can remove the `validates_presence_of` validation and instead change the validation message of `belongs_to` association. https://stackoverflow.com/questions/39019220/validation-error-messages-for-belongs-to-assocations-made-easy/44793180 – Deepesh Jul 16 '21 at 12:14
  • Thanks @deepesh, the combination of the rejection in your answer and the `belongs_to :location, optional: true` that's perfect. Thanks for your time. – John Fadria Jul 16 '21 at 12:54