[英]How to add a property/use method_missing approach to an ActiveRecord object in Rails?
I'm querying a mysql database and returning an array of objects created by a join. 我正在查询mysql数据库并返回由联接创建的对象数组。 From what I understand, the ActiveRecord select command returns an array of new objects, each with the properties of both tables in the join.
据我了解,ActiveRecord select命令返回一个新对象数组,每个对象都具有联接中两个表的属性。
I want to perform some calculations on each of these objects, and associate a few attributes with the object. 我想对这些对象中的每一个执行一些计算,并将一些属性与该对象相关联。 I understand that if this was my class, I could use the method_missing approach as seen here .
我知道,如果这是我的课程,则可以使用此处看到的method_missing方法。 However, since this object is created by the select command, I don't have class code where I can define the
add_attrs
function. 但是,由于此对象是由select命令创建的,因此我没有可定义
add_attrs
函数的类代码。 Is this possible? 这可能吗? Is using method_missing the correct approach and if so, how do I implement it?
使用method_missing是否使用正确的方法,如果是,该如何实现?
Here is the initial query which returns an array of ActiveRecord objects. 这是返回ActiveRecord对象数组的初始查询。
def self.select_with_location
select("advertisements.id, advertisements.weight, locations.latitude, locations.longitude")
end
If I were to go to the ruby console and type the commands 如果要转到ruby控制台并键入命令
advertisements = Advertisement.joins(:locations).select_with_location
puts advertisements[0].inspect
I should get something like: 我应该得到类似的东西:
{id: 0, weight: 5, locations.latitude: 49.03030, locations.longitude: 50.5050}
Now, what I want is to iterate through the advertisements and perform a calculation on each of the weights. 现在,我想要遍历广告并对每个权重进行计算。 I want to store the results of that calculation into a new attribute of advertisement, which I want to call
weight_multiplier
. 我想将计算结果存储到广告的新属性中,我将其称为
weight_multiplier
。 After this calculation, if I go to the ruby console and type the following command: 经过此计算后,如果我转到ruby控制台并键入以下命令:
puts advertisements[0].inspect
I would want to get the result 我想得到结果
{id:0, weight: 5, locations.latitude: 49.03030, locations.longitude: 50.5050, weight_multiplier: 0.446003}
In this example the numbers themselves aren't important, I just want to add the weight_multiplier attribute to each of the advertisements in the array. 在此示例中,数字本身并不重要,我只想向数组中的每个广告添加weight_multiplier属性。
I know the following code is incorrect, but this is the gist of what the function will do: 我知道以下代码不正确,但这是该函数将执行的要旨:
def self.assign_weight_multiplier advertisements
totalWeights = advertisements.inject(0){|sum,advertisement| sum + advertisement.weight }
advertisements.each do |advertisement|
advertisement.weight_multiplier = (Float(advertisement.weight)/Float(totalWeights))
end
advertisements
end
You can add 2 new methods to your Advertisement
class 您可以向自己的
Advertisement
类添加2个新方法
def total_weight
@total_weight ||= Advertisement.sum(:weight)
end
def weight_multiplier
self.weight.to_f / total_weight
end
then you can call weight_multiplier
as a instance method on Advertisement
instance 那么您可以将
weight_multiplier
用作Advertisement
实例的实例方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.