Search code examples
ruby-on-railsnested-attributesmodel-associations

Battling to display nested data in Rails


So I have a form with nested data that is correctly displaying in the form and is being correctly saved. However, I'm now working on trying to display this data and I'm really battling.

So I have a lot of data, but will focus on two specific types of data:

I have users, and users can create projects. The two data fields I'm battling with related to projects are:

  • Each project has a budget (stored as a budget_id on the project table, and for which I want to call the name of the budget)
  • Each project a bunch of features through a features_projects join table

Project Model

class Project < ApplicationRecord
  belongs_to :user
  has_one :budget
  has_and_belongs_to_many :features
end

Budget Model

class Budget < ApplicationRecord
  belongs_to :project
end

Features Model

class Feature < ApplicationRecord
  has_and_belongs_to_many :projects
end

Extract of the index method from the Projects Controller

def index
  @projects = Project.all
end

Project View to show the index

    <div class="container dashboard">
      <div class="center">
        <h1> Your Projects</h1>
      </div>
      <table class="table table-striped">
        <thead>
          <tr>
            <th>Description</th>
            <th>Budget</th>
            <th>User_id</th>
            <th colspan="3"></th>
          </tr>
        </thead>

        <tbody>
          <% @projects.each do |project| %>
            <tr>
              <% if project.user == current_user %>
                <td><%= project.description %></td>
                <td><%= project.budget_id %></td>
                <td><%= project.user.email if project.user %></td>
                <td><%= link_to 'Show', project, class: "btn btn-info btn-sm" %></td>
                <td><%= link_to 'Edit', edit_project_path(project), class: "btn btn-warning btn-sm" %></td>
                <td><%= link_to 'Destroy', project, class: "btn btn-danger btn-sm", method: :delete, data: { confirm: 'Are you sure?' } %></td>
              <% end %>
            </tr>
          <% end %>
        </tbody>
      </table>

      <br>
      <div class="center">
        <%= link_to 'New Project', new_project_path, class:"btn btn-lg btn-success" %>
      </div>
    </div>

I basically want to be able to display the budget saved for each project as well as the list of features that they chose. I have been trying a few different things from solutions online, but haven't had any luck :( I think perhaps I need to create a @budget variable perhaps under the index method, but I haven't had any luck with that either. Could anyone kindly help explain how I would do this?

Thanks so much!

UPDATE Using project.budget.name reveals the following error:

ActiveRecord::StatementInvalid in Projects#index

PG::UndefinedColumn: ERROR:  column budgets.project_id does not exist
LINE 1: SELECT  "budgets".* FROM "budgets" WHERE "budgets"."project_...

Solution

  • When you say that:

    Each project has a budget (stored as a budget_id on the project table, and for which I want to call the name of the budget)

    This is not how has_one works, it will expect a project_id on the budget table.

    I think you need to use belongs_to.

    http://guides.rubyonrails.org/association_basics.html#the-has-one-association