ruby-on-rails 在ApplicationRecord中添加Rails数据库表列值

h79rfbju  于 2023-10-21  发布在  Ruby
关注(0)|答案(2)|浏览(134)

我对Ruby Logic不感兴趣。所以我有一个Users表,其中有许多portfolios,投资组合表有一个amount列。我想为每个用户的投资组合的总金额添加到用户模型,我也希望它跳过用户投资组合中的nil值。
我做了这样的事

这是我的用户ActiveRecord

class User < ApplicationRecord
    has_secure_password
    has_many :assets
    has_many :portfolios

    validates :email, :first_name, :last_name, presence: true
    validates :email, uniqueness: { case_sensitive: false }
    validates :password, length: { in: 6..20 }

    def total_asset
        portfolios.amount.sum
    end
end

这是我的投资组合活跃记录

class Portfolio < ApplicationRecord
  belongs_to :asset
  belongs_to :user
end

我得到内部错误。就像我之前说的,我想跳过并避免添加具有nil值的投资组合金额

vfhzx4xs

vfhzx4xs1#

好吧,在尝试理解Ruby语法后,我能够想出这个简单的解决方案

def total_asset
        
        portfolios.collect{|portfolio| portfolio.valid? ? portfolio.amount : 0}.sum
    end

这将跳过无效或不存在的列

v8wbuo2f

v8wbuo2f2#

你不应该在Ruby中这样做。
有效的方法是在数据库中使用聚合函数:

User.group(:id)
    .left_joins(:portfolios)
    .select(
      User.arel_table[Arel.star], # all the columns from users
      Portfolio.arel_table[:amount].sum.as("portfolio_amount") # the aggregated count
    )

这避免了每次调用#total_asset方法时创建一个n+1查询,并避免从portfolios表中提取所有数据。如果你想进一步优化读取,你可以使用回调或counter_culture gem在users表上缓存聚合计数。

相关问题