user797963
user797963

Reputation: 3027

Rails - get results of many to many query without nested loops

I'm new to rails and am trying to figure out a better way to get the outputted data from a query on a many to many relationship.

Here are my models:

   class User < ActiveRecord::Base
      has_many :takes
      has_many :tests, through: :takes

      has_many :provides
      has_many :tests, through: :provides
    end

    class Test < ActiveRecord::Base
      has_many :takes
      has_many :users, through: :takes

      has_many :provides
      has_many :users, through: :provides
    end

    class Provide < ActiveRecord::Base
        belongs_to :user
        belongs_to :test
    end

    class Take < ActiveRecord::Base
        belongs_to :user
        belongs_to :test
    end

Here is my query:

@test = Test.includes(:users).where("id = ?", 1)

And here is how I'm working with the data, but I need to be able to for each row get the Test.* data, User.* data, and Provide.id. The Provide.id is the problem - I can't seem to get it.

    <% @test.each do |t| %>
        <% t.users.each do |u| %>
            <tr>
                <td><%= u.display_name %></td>
                <td><%= link_to g.name, waiting_area_path(t.id, u.id) %></td>
                <td><%= t.description %></td>
                <td><%= u.city + " - " + u.add_l1 %></td>
            </tr>
        <% end %>

When I try to access the Provide table data doing something like t.provides.each I can loop through all of the fields, but what I need is to grab the Provide.id from the row where I'm getting the Test.id and User.id.

For example, I try to add a line like this, but I get an error saying the method doesn't exist.

<% @test.each do |t| %>
    <% t.users.each do |u| %>
        <tr>
            <%= u.username +"|"+ t.provides.where('user_id ='+u.id)%>
            <td><%= link_to g.name, waiting_area_path(t.id, u.id) %></td>
            <td><%= t.description %></td>
            <td><%= u.city + " - " + u.add_l1 %></td>
        </tr>
    <% end %>

How can I get this data? These Active Record objects are getting to be a pain to work with...

Upvotes: 0

Views: 515

Answers (1)

jvnill
jvnill

Reputation: 29599

You need to differentiate between a take test and provide test, same with a user take and a user provide. Change the associations to

class User < ActiveRecord::Base
  has_many :takes
  has_many :take_tests, through: :takes

  has_many :provides
  has_many :provide_tests, through: :provides
end

class Test < ActiveRecord::Base
  has_many :takes
  has_many :take_users, through: :takes

  has_many :provides
  has_many :provide_users, through: :provides
end

Then use the following code to go through a list of users for a test.

@tests = Test.includes(provides: :user).where(tests: { id: 1 })

<% @tests.each do |test| %>
  <% test.provides.each do |provide| %>
    <tr>
      <td><%= link_to g.name, waiting_area_path(test, provide.user) %></td>
      <td><%= test.description %></td>
      <td><%= "#{provide.user.city} - #{provide.user.add_l1}" %></td>
    </tr>
  <% end %>
<% end %>

Upvotes: 1

Related Questions