user8165687
user8165687

Reputation:

Rails 5 Nested Resources for 3 models?

I have 3 models:

Report

has_many :report_items, dependent: :destroy

has_many :items, through: :report_items

Item

has_many :report_items, dependent: :destroy

has_many :reports, through: :report_items

ReportItem

belongs_to :item

belongs_to :report

I scaffolded all 3 models so now I have 3 separate views for each.

Right now if I wanted to assign an item to a report, I have to:

  1. Create new Item record

  2. Create new Report record

  3. Create new ReportItem record, using the id's of Item and Report to tie them together.

However what I need is for ReportItem to be nested inside Report. The idea is that after I create a new report, I can go to its "show" page and create "report_items" records from there. These "report_items" records automatically use the current "report" record's id.

I've gone to http://guides.rubyonrails.org/routing.html to research on how this would work. However, I'm still confused as to how to actually accomplish it.

Any tips on this?

Upvotes: 1

Views: 256

Answers (1)

Emu
Emu

Reputation: 5905

You can use accepts_nested_attributes_for. In you report create form,

<%= simple_form_for(@report) do |form| %>
  <%= form.input :title %>

  <%= form.simple_fields_for(:report_items) do |ri_form| %>
    <%= ri_form.input :name %>
  <% end %>

  <%= form.submit "Submit" %>
<% end %>

Then, Your Report model:

accepts_nested_attributes_for :report_items

In your ReportController, get the nested attributes:

private
def report_params
 params.require(:report).permit(:name, :report_items_attributes => [:name])
end

Check this answer for better view. Here is a good tutorial.

EDITED

Seems like you've created a new Report and then go the show page. In show page you want to create Report Item. So, when you go to the show page, the current url must contains the current report_id. All you need is Item_id. You can load all the items with IDs and create a dropdown to select the item_id. Then in the show page, report_item may look like:

<%= simple_form_for(@report_item) do |form| %>
  # in the current page @report contains the current report object  
  <%= form.input :report_id, as: hidden, value: @report.id %>
  # @items = Item.all
  <%= form.input :item_id, collection: @items, label_method: :item_name, value_method: :id, label: "Item", include_blank: false, selected: @report.item_id %>

  <%= form.submit "Submit" %>


<% end %>

Hope it helps!

Upvotes: 1

Related Questions