简体   繁体   English

Ruby - 如何从 Rails 命令加入 output?

[英]Ruby - how to join output from a Rails command?

There are multiple calculations I'd like to be able to perform on my database, all centred around a user id, but I don't know how to recombine them after.我希望能够在我的数据库上执行多项计算,所有计算都以用户 ID 为中心,但我不知道之后如何重新组合它们。

Let's say I have three tables for User , Purchases , and DiscountUsage .假设我有三个表UserPurchasesDiscountUsage I want to find the last date a user made a purchase and the total number of discounts used.我想找到用户购买的最后日期和使用的折扣总数。 I would run two separate commands:我会运行两个单独的命令:

User.joins(:purchases).group("users.id").select("users.id", "MAX(purchases.purchase_date)")
User.joins(:discount_usages).group("users.id").select("users.id", "COUNT(*)")

I want my final output to be one table though, joined on users.id , but the output from select isn't the right data type to work on with Rails functions.我希望我的最终 output 成为一张表,加入users.id ,但是来自select不是使用 Rails 函数的正确数据类型。 How can I represent that the users.id values from both calls are the same and thus join them based on those columns?我如何表示来自两个调用的users.id值是相同的,从而根据这些列加入它们?

You can select aggregates from joined tables and access them in the model by using aliases:您可以从连接表中聚合 select 并使用别名在 model 中访问它们:

@users = User.joins(:purchases, :discount_usages)
            .select(
              "users.id", 
              "MAX(purchases.purchase_date) AS latest_purchase",
              "COUNT(discount_usages.*) AS discount_usages_count"
            )
            .group("users.id")

If you want to hydrate the other attributes of the records select users.* instead of just users.id .如果您想水合记录 select users.*的其他属性,而不仅仅是users.id

<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Latest Purchase</th>
      <th>Discount usages</th>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
    <tr>
      <td><%= user.id %></td>
      <td><%= user.latest_purchase %></td>
      <td><%= user.discount_usages_count %></td>   
    </tr>
    <% end %>
  </tbody>
</table>

I want my final output to be one table though, joined on users.id, but the output from select isn't the right data type to work on with Rails functions.我希望我的最终 output 成为一张表,加入 users.id,但是来自 select 的 output 不是使用 Rails 函数的正确数据类型。

Not sure quite what you mean here.不太清楚你在这里的意思。 This example will return a collection of user records just like a normal query.此示例将像普通查询一样返回用户记录的集合。 If you want a "raw" result with just an array of arrays use .pluck instead of .select .如果您想要仅包含 arrays 数组的“原始”结果,请使用.pluck而不是.select

I assume a User may not have any purchases and not all purchases use discount codes.我假设用户可能没有任何购买,并且并非所有购买都使用折扣代码。

However, you want a full listing of each user with their last purchase date and total discount usages over all purchases.但是,您需要每个用户的完整列表,包括他们的最后购买日期和所有购买的总折扣使用情况。 You may need to use a right join.您可能需要使用右连接。

Something like:就像是:

query = User.select('users.id AS user_id', 'MAX(purchases.purchase_date) AS last_purchase_date', 'COUNT(discount_usages.id) AS total_discount_usages')
  .joins('LEFT JOIN purchases ON purchases.user_id = users.id')
  .joins('LEFT JOIN discount_usages ON discount_usages.user_id = purchases.user_id')
  .group('users.id')
  .to_sql

Then in order to grab the fields you could use:然后为了获取您可以使用的字段:

rows = ApplicationRecord.connection.select_all(query).to_hash

https://guides.rubyonrails.org/active_record_querying.html#select-all https://guides.rubyonrails.org/active_record_querying.html#select-all

This will give you an array of hashes with keys: 'user_id', 'last_purchase_date', 'total_discount_usages'.这将为您提供一个带有键的哈希数组:“user_id”、“last_purchase_date”、“total_discount_usages”。

...
<% rows.each do |row| %>
  <% row.symbolize_keys! %>
  <tr>
    <td><%= row[:user_id] %></td>
    <td><%= row[:last_purchase_date] %></td>
    <td><%= row[:total_discount_usages] %></td>
  <tr>
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM