【问题标题】:Rails 4 multi table join with data from all tablesRails 4 多表连接与所有表中的数据
【发布时间】:2017-06-13 12:25:08
【问题描述】:

我认为这很简单,但我就是不明白。我需要加入 3 个表并让 rails 从所有 3 个表中返回值。我已经完成了连接,但 rails 只返回 1 个表中的值。我想我只是不知道语法

这是我的控制器方法

@previous_results = Test.joins(:run, :detail).where("runs.name = ? AND tests.name = ?", @run.name, @test.name).last(1000)

这里的连接是来自它的sql

SELECT  `tests`.* FROM `tests` INNER JOIN `runs` ON `runs`.`id` = `tests`.`run_id` INNER JOIN `details` ON `details`.`test_id` = `tests`.`id` 
WHERE (runs.name = 'SNMSubscriberSpecificTemplatesFeedsTest' AND tests.name = 'testSitePrefixFalseForNTINSequentialList')  ORDER BY `tests`.`id` DESC LIMIT 1000

我需要做的就是从详细信息表中返回值。我想要从细节中获取 2 列值,而不是进行测试。* 我是 test.id、test.name、detail.text、detail.message 作为我的回报

Int active record 如何告诉它不仅返回测试表数据,还包括详细信息列

SQL 中的这个查询做了我想要知道的如何主动记录它

SELECT  `tests`.*, `details`.`detail_text`, `details`.`detail_error`
FROM `tests` 
INNER JOIN `runs` ON `runs`.`id` = `tests`.`run_id` 
INNER JOIN `details`   ON `tests`.`id` = `details`.`id`
WHERE (runs.name = 'SNMSubscriberSpecificTemplatesFeedsTest' AND tests.name = 'testSitePrefixFalseForNTINSequentialList')
ORDER BY `tests`.`id` DESC LIMIT 1000

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 activerecord


    【解决方案1】:
    @tests = Test
      .select('tests.*', 'details.detail_text', 'details.detail_error')
      .joins(:run, :detail)
      .where(
        runs: { name: 'SNMSubscriberSpecificTemplatesFeedsTest' },
        tests: { name: 'testSitePrefixFalseForNTINSequentialList' }
      )
      .limit(1000)
      .order(id: :desc)
    

    您的视图如下所示:

    <table>
      <tr>
        <th>Test ID</th>
        <th>Test Detail's Detail Text</th>
        <th>Test Detail's Detail Error</th>
      </tr>
      <% @tests.each do |test| %>
        <tr>
          <td><%= test.id %></td>
          <td><%= test.detail_text %></td>
          <td><%= test.detail_error %></td>
        </tr>
      <% end %>
    </table>
    

    建议:

    • 不要显式使用select() 来获取“关联值”,而是直接通过对象访问它们,如下所示

      @tests = Test
        .joins(:run, :detail).includes(:detail)
        .where(
          runs: { name: 'SNMSubscriberSpecificTemplatesFeedsTest' },
          tests: { name: 'testSitePrefixFalseForNTINSequentialList' }
        )
        .limit(1000)
        .order(id: :desc)
      

      您的视图将类似于:

      <table>
        <tr>
          <th>Test ID</th>
          <th>Test Detail's Detail Text</th>
          <th>Test Detail's Detail Error</th>
        </tr>
        <% @tests.each do |test| %>
          <tr>
            <td><%= test.id %></td>
            <td><%= test.detail.detail_text %></td>
            <td><%= test.detail.detal_error %></td>
          </tr>
        <% end %>
      </table>
      

    【讨论】:

    • previous_results = Test.joins(:run, :detail).where("runs.name = ? AND tests.name = ?", @run.name, @test.name).last( 1000) 将返回很多行我希望这些行中的每一行都包含详细信息表中的信息,所以我不确定你的建议是否可行。我的测试表包含许多测试的通过失败信息,详细信息表将 test.id 作为辅助键,它包含失败的实际详细信息。所以我想从测试中获取信息并添加该 test.id 的详细信息。如果这是有道理的。然后我将所有这些加载到数据表中进行显示
    • 我将我的答案更新为“包含详细信息”值,以便在加载 details 表值时只有一个查询而不是多个查询。这是你想要的吗?
    • 也许我没有得到这个我很抱歉。我的视图得到了 previous_results var 并在表中循环遍历它。我需要那个 var 来包含两个表中的数据。所以(伪代码)如果“测试”名称、ID 和详细信息“测试 ID、错误消息、错误文本”我希望 previous_results 有一个测试名称、测试 ID、detail.error 消息、detail.error 文本列表
    • 我刚刚更新了我的答案以包含一个呈现表格的“示例”视图代码(根据您的需要)
    猜你喜欢
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多