Deep Nesting Help

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Deep Nesting Help

John Sanderbeck
Here is a fun one for everyone...   

I have been struggling developing a form to do the following:

I have a Class with Students in it, and every day the teachers have to fill out a daily detail sheet which looks like this...

Untitled picture.png


Thank you in advance for any thoughts on this one... 

So what I have done is create a data scheme like this

dd_sheet
  dd_details
    dd_detail_categories
      dd_detail_items
       dd_detail_subitems
    dd_detail_subcategories
      dd_detail_items
        dd_detail_subitems

The sheet has the classroom, date and teacher...

The detail has a student, note and then Categories, Subcategories, Items, and Subitems

The Categories, Subcategories, Items, and Subitems are predefined from another set of tables and built when they create a new daily detail sheet

Model wise this all works great, so the relationships are correct

So on the form is where I am having the issue

Base Form is on DailyDetail

Need to step through each Category and display items related to that category first (including subitems related to the items)
Then step through each Subcategory and display items related to that category first (including subitems related to the items) 

Each Item/Subitem can have a check, a value, and/or a note so there is a check as to whether that value is needed. Here is the Item Table definition. Subitem is the same
------------
    create_table :dd_detail_items do |t|
      t.integer :dd_detail_category_id, null: true
      t.integer :dd_detail_subcategory_id, null: true
      t.string :title, null: false, length: 100
      t.boolean :has_check, default: false
      t.boolean :has_value, default: false
      t.boolean :has_note, default: false
      t.boolean :item_check, default: false
      t.string :item_value, default: ''
      t.text :item_note, default: ''
      t.timestamps null: false
    end
-------------

This is driving me bonkers trying to figure out this nesting....  I know logically how it should work but can't figure out the rails syntax to do it correctly...

Here are my models

dd_sheet
------------
  has_many :dd_details, dependent: :destroy
  belongs_to :classroom

  after_commit :build_nested, on: :create

  private

  def build_nested()
    classroom.students.each do |student|
      detail = DdDetail.create!(dd_sheet_id: id, student_id: student.id)
      # For each category, build the Items and Subcategories
      DdCategory.all.each do |category|
        # If the Category is active, build it
        if category.is_active?
          cat = detail.dd_detail_categories.create!(title: category.title)
          # Now build any items directly related to this Category
          category.dd_items.each do |item|
            # If the item is active, build it
            if item.is_active?
              newitem = cat.dd_detail_items.create!(dd_detail_category_id: cat.id, title: item.title, has_check: item.has_check, has_value: item.has_value, has_note: item.has_note, item_check: item.item_check, item_value: item.item_value, item_note: item.item_note)
              # If the item is has SubItems, build them
              if item.dd_subitems.count > 0
                item.dd_subitems.each do |subitem|
                  newitem.dd_detail_subsubitems.create!(dd_detail_item_id: newitem.id, title: subitem.title, has_check: subitem.has_check, has_value: subitem.has_value, has_note: subitem.has_note, item_check: subitem.item_check, item_value: subitem.item_value, item_note: subitem.item_note)
                end
              end
            end
          end
          category.dd_subcategories.each do |subcategory|
            # If the Subcategory is active, build it
            if subcategory.is_active?
              subcat = cat.dd_detail_subcategories.create!(title: subcategory.title)
              subcategory.dd_items.each do |item|
                # If the item is active, build it
                if item.is_active?
                  newitem = subcat.dd_detail_items.create!(dd_detail_category_id: subcat.id, title: item.title, has_check: item.has_check, has_value: item.has_value, has_note: item.has_note, item_check: item.item_check, item_value: item.item_value, item_note: item.item_note)
                  # If the item is has SubItems, build them
                  if item.dd_subitems.count > 0
                    item.dd_subitems.each do |subitem|
                      newitem.dd_detail_subitems.create!(dd_detail_item_id: newitem.id, title: subitem.title, has_check: subitem.has_check, has_value: subitem.has_value, has_note: subitem.has_note, item_check: subitem.item_check, item_value: subitem.item_value, item_note: subitem.item_note)
                    end
                  end
                end
              end
            end
          end
        end
      end  
    end
  end
------------


dd_detail
------------
  belongs_to :dd_sheet
  has_many :dd_detail_categories, dependent: :destroy
  belongs_to :student
------------


dd_detail_category
------------
  belongs_to :dd_detail
  has_many :dd_detail_subcategories, dependent: :destroy
  has_many :dd_detail_items, dependent: :destroy
  accepts_nested_attributes_for :dd_detail_items, allow_destroy: true
------------


dd_detail_subcategories
------------
  belongs_to :dd_detail_category
  has_many :dd_detail_items, dependent: :destroy
  accepts_nested_attributes_for :dd_detail_items, allow_destroy: true
------------


dd_detail_items
------------
  belongs_to :dd_detail_category
  belongs_to :dd_detail_subcategory
  has_many :dd_detail_subitems, dependent: :destroy
  accepts_nested_attributes_for :dd_detail_subitems, allow_destroy: true
------------


dd_detail_subitems
------------
  belongs_to :dd_detail_item
------------


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/029fe73d-4938-4b56-9c4c-be5e011cc280%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Deep Nesting Help

John Sanderbeck

Another thing to note is I am also only doing an Edit of the data as the records already have been created and are not allowed to be destroyed.

John 

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Deep Nesting Help

Ariel Juodziukynas
I'm not sure I understand what's the problem, where exactly do you have doubts?

I'd suggest you first refactor that super ugly nested loops and ifs:
- remove the unnecesarry if's
    DdCategory.all.each do |category|
      # If the Category is active, build it
      if category.is_active?

can't you handle that is_active? with a scope?

- the blocks for category.dd_items and subcategory.dd_items looks almost the same, I think you can reuse some code there

- move complex logic to other methods to clean that up, like:

                    item.dd_subitems.each do |subitem|
                      newitem.dd_detail_subitems.create!(dd_detail_item_id: newitem.id, title: subitem.title, has_check: subitem.has_check, has_value: subitem.has_value, has_note: subitem.has_note, item_check: subitem.item_check, item_value: subitem.item_value, item_note: subitem.item_note)
                    end

could be a method on newitem like "add_subitem_from(subitem)" that does that create but you'll have less clutter to simplify your logic to understand it better


El jue., 26 sept. 2019 a las 16:01, John Sanderbeck (<[hidden email]>) escribió:

Another thing to note is I am also only doing an Edit of the data as the records already have been created and are not allowed to be destroyed.

John 

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/CAPS3bcDL%2Bu4RcvNAEOdAV0q44dnD6OFOJ2BXT%2BoFxhKiyPOuBw%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Deep Nesting Help

John Sanderbeck
I agree I can clean up the build but the problem I am having is in the form, not the models...

I need to structure the nested form and I can't seem to figure out the rails syntax...

Just experimenting, and currently, this is the closest I have gotten to what I am trying to do...

  <% @dd_detail.dd_detail_categories.each do |category| %>
    <div class="lunch_order_list_class"><%= category.title.titleize %></div>
    <%= f.fields_for :dd_detail_items do |item| %>
        <%= item.label :title %>
        <%= item.check_box :item_check %>
        <%= item.text_field :item_value %>
        <%= item.text_area :note %>
      <br/>
      <%= item.fields_for :dd_detail_subitems do |subitem| %>
          <%= subitem.label :title %>
          <%= subitem.check_box :item_check %>
          <%= subitem.text_field :item_value %>
          <%= subitem.text_area :note %>
        <br/>
      <% end %>
    <% end %>
    <%= f.fields_for :dd_detail_subcategories do |subcategory| %>
      <%= subcategory.label :title %><br/>
      <%= subcategory.fields_for :dd_detail_items do |item| %>
          <%= item.label :title %>
          <%= item.check_box :item_check %>
          <%= item.text_field :item_value %>
          <%= item.text_area :note %>
        <br/>
        <%= item.fields_for :dd_detail_subitems do |subitem| %>
            <%= subitem.label :title %>
            <%= subitem.check_box :item_check %>
            <%= subitem.text_field :item_value %>
            <%= subitem.text_area :note %>
          <br/>
        <% end %>
      <% end %>
    <% end %>
  <% end %>




On Thursday, September 26, 2019 at 4:25:03 PM UTC-4, Ariel Juodziukynas wrote:
I'm not sure I understand what's the problem, where exactly do you have doubts?

I'd suggest you first refactor that super ugly nested loops and ifs:
- remove the unnecesarry if's
    DdCategory.all.each do |category|
      # If the Category is active, build it
      if category.is_active?

can't you handle that is_active? with a scope?

- the blocks for category.dd_items and subcategory.dd_items looks almost the same, I think you can reuse some code there

- move complex logic to other methods to clean that up, like:

                    item.dd_subitems.each do |subitem|
                      newitem.dd_detail_subitems.create!(dd_detail_item_id: <a href="http://newitem.id/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fnewitem.id%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHBrAKxHrJRTdb-fy9jpIt0AOHCOg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fnewitem.id%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHBrAKxHrJRTdb-fy9jpIt0AOHCOg&#39;;return true;">newitem.id, title: subitem.title, has_check: subitem.has_check, has_value: subitem.has_value, has_note: subitem.has_note, item_check: subitem.item_check, item_value: subitem.item_value, item_note: subitem.item_note)
                    end

could be a method on newitem like "add_subitem_from(subitem)" that does that create but you'll have less clutter to simplify your logic to understand it better


El jue., 26 sept. 2019 a las 16:01, John Sanderbeck (<<a href="javascript:" target="_blank" gdf-obfuscated-mailto="pgJ2UTD7BAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">band...@...>) escribió:

Another thing to note is I am also only doing an Edit of the data as the records already have been created and are not allowed to be destroyed.

John 

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="pgJ2UTD7BAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">rubyonra...@googlegroups.com.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com?utm_medium=email&amp;utm_source=footer" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/424ef245-ea1a-410e-89ca-797bec4712f2%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Deep Nesting Help

Ariel Juodziukynas
But what's the actual problem? you say you have some problem but you just pasted code with no indication on where to look. Do you have a render error? do you have the view rendering ok but when you submit it it does not do what you want? if it does not do what you want, what's the excepted vs the actual behaviour?

El jue., 26 sept. 2019 a las 22:24, John Sanderbeck (<[hidden email]>) escribió:
I agree I can clean up the build but the problem I am having is in the form, not the models...

I need to structure the nested form and I can't seem to figure out the rails syntax...

Just experimenting, and currently, this is the closest I have gotten to what I am trying to do...

  <% @dd_detail.dd_detail_categories.each do |category| %>
    <div class="lunch_order_list_class"><%= category.title.titleize %></div>
    <%= f.fields_for :dd_detail_items do |item| %>
        <%= item.label :title %>
        <%= item.check_box :item_check %>
        <%= item.text_field :item_value %>
        <%= item.text_area :note %>
      <br/>
      <%= item.fields_for :dd_detail_subitems do |subitem| %>
          <%= subitem.label :title %>
          <%= subitem.check_box :item_check %>
          <%= subitem.text_field :item_value %>
          <%= subitem.text_area :note %>
        <br/>
      <% end %>
    <% end %>
    <%= f.fields_for :dd_detail_subcategories do |subcategory| %>
      <%= subcategory.label :title %><br/>
      <%= subcategory.fields_for :dd_detail_items do |item| %>
          <%= item.label :title %>
          <%= item.check_box :item_check %>
          <%= item.text_field :item_value %>
          <%= item.text_area :note %>
        <br/>
        <%= item.fields_for :dd_detail_subitems do |subitem| %>
            <%= subitem.label :title %>
            <%= subitem.check_box :item_check %>
            <%= subitem.text_field :item_value %>
            <%= subitem.text_area :note %>
          <br/>
        <% end %>
      <% end %>
    <% end %>
  <% end %>




On Thursday, September 26, 2019 at 4:25:03 PM UTC-4, Ariel Juodziukynas wrote:
I'm not sure I understand what's the problem, where exactly do you have doubts?

I'd suggest you first refactor that super ugly nested loops and ifs:
- remove the unnecesarry if's
    DdCategory.all.each do |category|
      # If the Category is active, build it
      if category.is_active?

can't you handle that is_active? with a scope?

- the blocks for category.dd_items and subcategory.dd_items looks almost the same, I think you can reuse some code there

- move complex logic to other methods to clean that up, like:

                    item.dd_subitems.each do |subitem|
                      newitem.dd_detail_subitems.create!(dd_detail_item_id: newitem.id, title: subitem.title, has_check: subitem.has_check, has_value: subitem.has_value, has_note: subitem.has_note, item_check: subitem.item_check, item_value: subitem.item_value, item_note: subitem.item_note)
                    end

could be a method on newitem like "add_subitem_from(subitem)" that does that create but you'll have less clutter to simplify your logic to understand it better


El jue., 26 sept. 2019 a las 16:01, John Sanderbeck (<[hidden email]>) escribió:

Another thing to note is I am also only doing an Edit of the data as the records already have been created and are not allowed to be destroyed.

John 

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/56b5ef26-e7ed-45a8-b346-b39c45edca0f%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/424ef245-ea1a-410e-89ca-797bec4712f2%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/CAPS3bcDDVGfEPi9AXkdHeC3ZxhCN6ecqA4smkwKcnoJdw_pBPA%40mail.gmail.com.