Rails - 在没有嵌套循环的情况下获得多对多查询的结果

时间:2014-03-10 02:44:30

标签: ruby-on-rails activerecord

我是rails的新手,我正试图找出一种更好的方法来从多对多的关系中获取查询的输出数据。

以下是我的模特:

   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

这是我的问题:

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

以下是我如何使用数据,但我需要能够为每一行获取Test。*数据,User。*数据和Provide.id。 Provide.id是问题 - 我似乎无法得到它。

    <% @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 %>

当我尝试访问Provide表数据时,执行类似t.provides.each的操作,我可以循环遍历所有字段,但我需要从我正在获取测试的行中获取Provide.id .id和User.id.

例如,我尝试添加这样的行,但是我收到错误,说该方法不存在。

<% @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 %>

我如何获得这些数据?这些Active Record对象变得很麻烦......

1 个答案:

答案 0 :(得分:1)

您需要区分测试和提供测试,与用户拍摄和用户提供相同。将关联更改为

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

然后使用以下代码浏览测试用户列表。

@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 %>