4

I'm using Simple Form in my Rails 6 e-commerce inventory tracking, and I need to have multiple collection selects in my form that appear based on an association.

Here's the data model:

Product
   has_many Option(s)
Option
   has_many Choice(s)
   belongs_to Product
Choice
   has_many Variant(s)
   belongs_to Option
Variant
   belongs_to Choice(s)

So a Product might look like this:

Product => T-Shirt
Options => Size { choices: small, medium, large }, Color { choices: red, green, blue }
Variant #1 => T-Shirt in Medium Red, etc.

How do I build the collection selects for the Product Options when not every product will have the same number of options that the customer will need to choose such as size or color? Some products might have 0 options, others 1 (e.g. just color), 2 (e.g. size and color), 3, etc.

So, on the Variant form I'd like to gather the collections that belong to the associated product. I can show them on the Variant#show view like this:

<ul>
  <% @product.options.each do |option| %>
    <li>
      <%= option.name %>
      <ul>
        <% option.choices.each do |choice| %>
          <li><%= choice.name %></li>
        <% end %>
      </ul>
    </li>
  <% end %>
</ul>

That works as expected in the Variants#show view.

But how do you do this same sort of thing and gather 0 or more Options with their associated choices in the Variant form with a collection_select? I'm using simple form, so I'm trying something like this, but it's not working and I'm blocked:

<% @variant.product.options.each do |option| %>
    <div class='form-row'>
      <div class='col'>
        <%= f.label option.name %>
        <% option.choices.each do |choice| %>
          <%= f.association choice %>
        <% end %>
      </div><!-- /.col -->
    </div><!-- /.form-row -->
  <% end %>

That version of the form gives me the following error:

RuntimeError in Variants#edit

enter image description here

Lee McAlilly
  • 9,084
  • 12
  • 60
  • 94
  • 1
    Can you please also elaborate a bit on what exactly you mean by not working, if there is a error, pasting that is also helpful. – Zia Ul Rehman Mughal Jun 18 '19 at 18:19
  • Good point. Just edited it to include the error. @ Zia Ul Rehman Mughal – Lee McAlilly Jun 18 '19 at 19:30
  • 1
    Its been long since i used simple_form(have been working on frontend frameworks now) but quick look in https://github.com/plataformatec/simple_form suggests you need to provide name of asssociation, not single objects. And what i have used and like most is the nested forms, with accepts_nested_attributes_for defined in model chains. Like the block method from https://www.rubydoc.info/github/plataformatec/simple_form/master/SimpleForm%2FFormBuilder:association – Zia Ul Rehman Mughal Jun 19 '19 at 05:22
  • Thanks. Zia. I guess I'm wondering how to pass in the name of the association through the block. If I do `<%= f.association choice.name %>` I get an error such as, `Association "Red" not found` – Lee McAlilly Jun 19 '19 at 20:52
  • 1
    Maybe try something like this: <%= f.association choice, label_method: :name, value_method: :id %>` – Jake Jun 27 '19 at 21:50
  • Thanks Jake. I get the same error when trying that. I feel like I'm missing something fundamental about how I'm approaching this problem. – Lee McAlilly Jul 02 '19 at 16:02
  • Could the issue be that I'm trying to do this in the edit form and there are no associations created that are available in the edit action? If I try to use `<%= f.association choice, label_method: :name, value_method: :id %>` on the new action I get a no method error `undefined method `options' for nil:NilClass`. Which makes sense because I haven't associated the variant with a product and its associated options yet. So perhaps I need a nested form on variant#new to create the associations and then I'll be able to access them in the form or variant views, etc. – Lee McAlilly Jul 03 '19 at 15:50
  • @LeeMcAlilly yes, try that. Makes sense. – Zia Ul Rehman Mughal Jul 04 '19 at 06:41
  • 1
    I'm kind of wondering how options, choices, and product are being called in other ways besides Option, Choice, or Product. Are you defining these methods in your controller? Or, as an object (or variable, IDK the jargon) in the case as `@product` and `@variant`? Please show your controller, you may even be missing something in your params. – Jake Jul 09 '19 at 12:04
  • @Jake Yes they are objects, not methods. Here's the ProductsController: https://gist.github.com/leemcalilly/b044805f1c40612deaf618cbfe6a24b6 //// OptionsController: https://gist.github.com/leemcalilly/3aa5ce49fe423e7259db34b8c7f43cff ///// ChoicesController: https://gist.github.com/leemcalilly/2c0262fdf14a8ef9537084c26d52f254 – Lee McAlilly Jul 10 '19 at 16:12

0 Answers0