gpt4 book ai didi

ruby-on-rails - 在对象数组上使用 ActiveRecord getter

转载 作者:数据小太阳 更新时间:2023-10-29 07:34:27 25 4
gpt4 key购买 nike

如何在 Ruby 中为 ActiveRecord 对象定义自定义 getter 函数,以对 ActiveRecord 对象数组执行操作?

例如,我想返回对象数组的加权平均值。因此,如果我有贷款对象 (1,2,3),其字段金额为 (100, 200, 300) 和 default_rate (.1, .2, .3),然后使用正常的 ActiveRecord 函数 Loan.find(1).amount应该返回 100,Loan.find(2).default_rate 应该返回 .2。

但如果我有 Loan.find(2,3).default_rate,我希望它返回违约率的加权平均值,即 .26。我知道我可以使用 SQL select 语句来做到这一点,但是当我在 Loan 对象数组而不是单个 Loan 对象上调用 getter 时,如何“重载”ActiveRecord getter 以允许定义函数?

贷款表有字段 amount id, amount, and default_rate

class Loan < ActiveRecord::Base
module Collection
def default_rate
sum(:default_rate * :amount) / sum(:amount)
end
end
end

class LoanGroup
has_many :loans, :extend => Loan::Collection
end

#Then I try
obj = LoanGroup.where('id < 10')

这给我的错误是 has_many 在 LoanGroup 中未定义

最佳答案

为了避免 Array 的命名空间被特定于 Loan 记录集合的方法污染,您可以为这样的集合创建一个包装器并在其上调用您的方法。

类似于:

class LoanArray < Array
def initialize(*args)
find(*args)
end

def find(*args)
replace Array.wrap(Loan.find(*args))
self
end

def default_rate
if length == 1
self[0].default_rate
else
inject(0) {|mem,loan| mem + loan.defualt_rate } / count
end
end
end

# then
arr = LoanArray.new(2,3).default_rate #=> 0.26
arr.find(1,2,3).default_rate #=> 0.2
arr.length #=> 3
arr.find(1) #=> [<Loan id=1>]
arr.default_rate #=> 0.1
arr.length #=> 1

下面的原始答案:使用关联扩展

使用关联扩展。这样,无论是贷款还是贷款集合,方法都是一样的。

class MyClass
has_many :loans do
def default_rate
sum(:default_rate) / count
end
end
end

obj = MyClass.find(1)
obj.loans.first.default_rate #=> 0.1
obj.loans.default_rate #=> 0.2
obj.loans.where(:id => [2,3]).default_rate #=> 0.26

如果你想在 Loan 类中保留贷款逻辑,你也可以在那里编写扩展,例如:

class Loan
module Collection
def default_rate
sum(:default_rate) / count
end

# plus other methods, as needed, e.g.
def average_amount
sum(:amount) / count
end
end
end

class MyClass
has_many :loans, :extend => Loan::Collection
end

编辑:正如@Santosh 指出的那样,association.find 不返回关系,因此在这里不起作用。您必须使用 where 或其他返回关系的方法。

关于ruby-on-rails - 在对象数组上使用 ActiveRecord getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13313076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com