1

I used group_by to get a certain desired result. Based on the explanation in the answer, I have updated my question to reflect the answer, to see the steps it took to arrive at a solution, see the edit history.

@grouped_test_specific_reports = TestSpecificReport.all.group_by(&:equipment_type_name)

The code above produced this result:

    2.5.1 :026 > pp @grouped_test_specific_reports
{"Ultrasonic Probes"=>
  [#<TestSpecificReport:0x00007f832aa2d6e0
    id: 10,
    equipment_type_id: 2,
    test_method_id: 1,
    equipment_amount: "Multiple",
    equipment_heading: "UT Probes">],
 "Ultrasonic Instruments"=>
  [#<TestSpecificReport:0x00007f832aa2d3c0
    id: 8,
    equipment_type_id: 1,
    test_method_id: 1,
    equipment_amount: "Single",
    equipment_heading: "UT Instrument">],
 "Visual Test Equipment"=>
  [#<TestSpecificReport:0x00007f832aa2cfb0
    id: 11,
    equipment_type_id: 4,
    test_method_id: 1,
    equipment_amount: "Single",
    equipment_heading: "VT Equipment">]}
 => {"Ultrasonic Probes"=>[#<TestSpecificReport id: 10, equipment_type_id: 2, test_method_id: 1, equipment_amount: "Multiple", equipment_heading: "UT Probes">], "Ultrasonic Instruments"=>[#<TestSpecificReport id: 8, equipment_type_id: 1, test_method_id: 1, equipment_amount: "Single", equipment_heading: "UT Instrument">], "Visual Test Equipment"=>[#<TestSpecificReport id: 11, equipment_type_id: 4, test_method_id: 1, equipment_amount: "Single", equipment_heading: "VT Equipment">]} 

My next goal is to list out the grouped test specific report in the browser by their keys, I was able to do that by @grouped_test_specific_reports.each { |key, value| puts key }

  • "Visual Test Equipment"
  • "Ultrasonic Instruments" and
  • "Ultrasonic Probes"

Now we have to iterate over the values, which happens to be an array, in another loop to be able to compare equipment_amount.

The values with equipment_amount: "Multiple" will have the plus icon in front of them, and the ones with equipment_amount: "Single" will simply be a drop-down:

Here's the code for the UI:

- @grouped_test_specific_reports.each do |equipment_type_name, test_specific_reports|
  .form-group.row
    .col-sm-6
      %label
        = equipment_type_name
      = select_tag '', options_from_collection_for_select(test_specific_reports, :id, :equipment_heading), { include_blank: "Select #{equipment_type_name} List", class: 'form-control select2', style: 'width: 100%;' }
    .col-sm-1
      - test_specific_reports.each do |test_specific_report|
        - if test_specific_report.equipment_amount == 'Multiple'
          .icon.text-center
            %i.fa.fa-plus-circle.add-icon
18
  • I'm not clear... if you have two "Ultrasonic Probes" and only one is "multiple" do you want the Plus icon to appear next to the whole selector, or just next to the specific drop down entry that has "multiple"? Commented Dec 30, 2018 at 13:12
  • Yes, I have 2 "Ultrasonic Probes" and 2 "Ultrasonic Instruments" that both have Multiple and Single equipment_amount, but I only want the plus icon to appear next to Ultrasonic Probes, that has Multiple equipment_amount and Ultrasonic Instruments that have multiple equipment_amount. Commented Dec 30, 2018 at 13:16
  • So the plus icon before the drop down should only appear if an item with "Multiple" is selected? If you change the selection to an item of type "Single" the plus should disappear? What happens when you click the plus icon? Is another select element created that only contains items in the same group that have "Multiple"? What should happen when an item with "Multiple" is selected, the plus icon is clicked and then the value is changed back to one that has "Single"? Commented Dec 30, 2018 at 13:24
  • Thanks, @JohanWentholt very good questions, yes, the plus should only appear when an item with Multiple is selected. If the selected item is changed from an item with a type of Multiple to a type of Single the plus icon should disappear. When the Plus Icon is clicked, an item is created and inserted into a join table between the current model "Report" and the "Equipment" table. After Plus icon is clicked the field should go back to the default value "Ultrasonic Probe List" for example. Commented Dec 30, 2018 at 13:33
  • I personally think there might be something wrong with the design. You might want to give the groups their own model/table, since this seems like an attribute that should be set on the group instead. Alternatively (while still using a group model) you might want to specify a certain amount of inventory slots a group has. Each selectable item takes up X amount of slots. Then set up a validation to make sure that the sum of inventory slots of the selected items take op less or equal the amount of inventory slots a the group has. Commented Dec 30, 2018 at 13:34

1 Answer 1

1

I personally found the question you're asking a bit unclear. For this reason I discussed some things in the comments with you. From our discussion in the comments it seemed you simply wanted to loop through the grouped values for each group.

First I want to clear up what group_by exactly does, because this seemed to be the issue. A simple misunderstanding of what you're currently working on.

group_by { |obj| block } → a_hash

group_by → an_enumerator

Groups the collection by result of the block. Returns a hash where the keys are the evaluated result from the block and the values are arrays of elements in the collection that correspond to the key.

If no block is given an enumerator is returned.

(1..6).group_by { |i| i%3 }   #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

The documentation makes clear that the grouped hash has keys that evaluate from the block (the return value). The value that belongs to the key is actually an list of values that evaluate to the same result. This means you can simply loop through the values in the following way.

grouped_values = (1..6).group_by { |n| n % 3 }

grouped_values.each do |key, values|
  puts "Key: #{key}"

  values.each do |value|
    puts "Value: #{value}"
  end
end

The first each loops through the groups. The second each loops through the values of the group. Since you loop though two different things you can't change this into a single loop easily. The important thing to remember here that the value belonging to a group key is not a single value, but rather a group of values (array).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.