首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rails和Arel表中使用不同的方法?

如何在Rails和Arel表中使用不同的方法?
EN

Stack Overflow用户
提问于 2022-05-19 16:06:40
回答 1查看 139关注 0票数 0

我希望在Rails中运行以下查询(我已经使用scuttle.io站点将我的SQL转换为rails友好的语法):

以下是原始查询:

代码语言:javascript
复制
SELECT pools.name AS "Pool Name", COUNT(DISTINCT stakings.user_id) AS "Total Number of Users Per Pool" from stakings
INNER JOIN pools ON stakings.pool_id = pools.id
INNER JOIN users ON users.id = stakings.user_id
INNER JOIN countries ON countries.code = users.country
WHERE countries.kyc_flow = 1
GROUP BY (pools.name);

下面是scuttle.io查询:

代码语言:javascript
复制
    <%Staking.select(
    [
      Pool.arel_table[:name].as('Pool_Name'), Staking.arel_table[:user_id].count.as('Total_Number_of_Users_Per_Pool')
    ]
    ).where(Country.arel_table[:kyc_flow].eq(1)).joins(
      Staking.arel_table.join(Pool.arel_table).on(
        Staking.arel_table[:pool_id].eq(Pool.arel_table[:id])
      ).join_sources
    ).joins(
      Staking.arel_table.join(User.arel_table).on(
        User.arel_table[:id].eq(Staking.arel_table[:user_id])
      ).join_sources
    ).joins(
      Staking.arel_table.join(Country.arel_table).on(
        Country.arel_table[:code].eq(User.arel_table[:country])
      ).join_sources
    ).group(Pool.arel_table[:name]).each do |x|%>
<p><%=x.Pool_Name%><p>
<p><%=x.Total_Number_of_Users_Per_Pool%>
<%end%>

现在,正如您可能注意到的,sctuttle.io不包括我需要的不同参数。在这个世界上,我如何在这里使用distinct而不出现诸如“Arel Node不存在不同的方法”之类的错误?还是只是语法错误?

是否有任何方法可以使用rails ActiveRecord编写上述查询?我肯定有,但我真的不知道怎么做。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-19 17:44:00

应答 Arel::Nodes::Count类( Arel::Nodes::Function)接受布尔值作为区分。

代码语言:javascript
复制
def initialize expr, distinct = false, aliaz = nil
  super(expr, aliaz)
  @distinct = distinct
end

#count表达式是相同参数的快捷方式,并接受单个参数。

代码语言:javascript
复制
def count distinct = false
  Nodes::Count.new [self], distinct
end

因此,在您的情况下,您可以使用以下任何一个选项

代码语言:javascript
复制
Arel::Nodes::Count.new([Staking.arel_table[:user_id]],true,'Total_Number_of_Users_Per_Pool')
# OR
Staking.arel_table[:user_id].count(true).as('Total_Number_of_Users_Per_Pool')

建议1:您的Arel看起来有点过分了。考虑到自然的关系,你应该能够把这个简化一些。

代码语言:javascript
复制
country_table = Country.arel_table
Staking
  .joins(:pools,:users)
  .joins( Arel::Nodes::InnerJoin(
            country_table, 
            country_table.create_on(country_table[:code].eq(User.arel_table[:country])))
  .select( 
     Pool.arel_table[:name],
     Staking.arel_table[:user_id].count(true).as('Total_Number_of_Users_Per_Pool')
   )
  .where(countries: {kyc_flow: 1})
  .group(Pool.arel_table[:name])

建议2:将此查询移至控制器。视图没有进行数据库调用的必要。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72307775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档