0
votes

I am trying to display the output of this find -

@test = User.joins(:plans => [:categories => [:project => :presentations]]).where(current_user.id)

Here is my output loop

<% @test.each do |p| %>
  <%= p.plans %>
  <% p.plans.each do |d| %>
    <%= debug(d) %>
    <% d.categories.each do |e| %>
      <% e.project.each do |r| %>
       <%= debug(r) %>
      <% end %>
<% end %>
  <% end %>
<% end %>

The loop works until it gets to project when it throws this error

undefined method `each' for "#<Project:0x000001033d91c8>":Project

If I change it to projects in the loop it gives this error

undefined method `projects' for #<Plan:0x000001033da320>

The debug at categories level shows this

--- !ruby/object:Category 
attributes: 
 id: 2
 name: test
 short_name: tst
 created_at: 
 updated_at: 
 category_id: 2
 plan_id: 5

My relationships look like this

User has_many :user_plans Plan has_many :user_plans has_and_belongs_to_many :categories Category has_one :project has_and_belongs_to_many :plans Project has_many :presentations, :dependent => :delete_all Presentation belongs_to :project

Do I need to changed my find ?

Thanks, Alex

3

3 Answers

1
votes

Category has_one :project

so it is single object not collection thus no each method.

1
votes

According to your relationship definitions, Category only has_one project, so why do you want to iterate over e.project? If you just want to show debugging output, replace

<% e.project.each do |r| %>
  <%= debug(r) %>
<% end %>

with

<%= debug(e.project) %>

But if you want to go deeper, into presentations, do:

<%= debug(e.project) %>
<% e.project.presentations.each do |presentation| %>
  <%= debug(presentation) %>
<% end %>
1
votes

Your problem is that you are calling the array method .each on a single object.

category.project will give you a single Project object right? That's not an array, so you can't call each on it.

Replace this:

<% e.project.each do |r| %>
 <%= debug(r) %>
<% end %>

with

debug(e.project)

While you're at it, here's some other advice: use descriptive variable names. Why does 'p' represent a test, 'd' represent a plan, 'e' represent a category, etc? Variable names should tell you what the object is. Similarly, i'd expect the variable @test to hold a Test object. In your code it seems to be an array. Use plural variable names for a variable that holds a collection of that type of object - eg @plans would be an array of Plan objects.

eg

<% @tests.each do |test| %>
  <% test.plans.each do |plan| %>
    <%= debug(plan) %>
    <% plan.categories.each do |category| %>
     <%= debug(category.project) %>
    <% end %>
  <% end %>
<% end %>

Isn't that more readable?