0

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...

1 Answer 1

1

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 %>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I actually didn't need to modify the associations, but the query and code to loop through the results was exactly what I needed. Clears up my confusion, appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.