计算总的百分比从范围记录和显示虚拟属性(轨道/活动记录) [英] Calculate Percent of total from scoped records and display virtual attributes (Rails / Active Record)

查看:115
本文介绍了计算总的百分比从范围记录和显示虚拟属性(轨道/活动记录)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建范围,也许是这样的。

 范围:MV,选择(*,数量* market_​​price为market_​​value,数量* market_​​price /总和(数量* market_​​price)以百分比)
 

这是创建两个虚拟属性,market_​​value和百分比。我遇到的问题是,与和创造的百分比()包括在内。如果我添加和(),适用范围,将返回一个记录。

我需要计算market_​​value相对的百分比的范围内的记录集的总市值。

例如:

  1,market_​​value:100,百分比为:0.10
2,market_​​value:100,百分比为:0.10
3,market_​​value:100,百分比为:0.10
4,market_​​value:100,百分比为:0.10
5,market_​​value:100,百分比为:0.10
6,market_​​value:500,百分比为:0.50
合计为1000
 

不过,如果我范围是指到market_​​value< 6,我应该看到

  1,market_​​value:100,百分比为:0.20
2,market_​​value:100,百分比为:0.20
3,market_​​value:100,百分比为:0.20
4,market_​​value:100,百分比为:0.20
5,market_​​value:100,百分比为:0.20
总计500
 

我怎样才能做到这一点?

我创建一个self.pct的方法,但问题与self.pct方法是它需要所有范围后运行。如果rescoped,解决的办法是错误的。

到目前为止,

 类职位<的ActiveRecord :: Base的
  attr_accessible:ACCOUNT_ID,:ACCOUNT_TYPE,:market_​​price,:数量:report_date,:符号

  适用范围:long_only,其中(:ACCOUNT_TYPE =>'L')
  范围:short_only,其中(:ACCOUNT_TYPE =>中S)
  适用范围:equity_only,:条件=> [符号LT;>'美元']

 适用范围:MV,选择(*,数量* market_​​price为market_​​value,数量* market_​​price /总和(数量* market_​​price)以百分比)

 适用范围:MV1,拉姆达{|总|选择(总)}

  #系统问题与self.pct方法是它需要所有范围后运行。如果rescoped,解决的办法是错误的

 高清self.pct
   字符串=*,(数量* market_​​price)为market_​​value,(market_​​price *量/#{sum_market_​​value})的百分比
   MV1(串)
 结束


  高清market_​​value
    self.market_​​price * self.quantity
  结束


  高清self.sum_market_​​value
    和('数量* market_​​price)
  结束
结束
 

解决方案

我不知道是否有一种方法可以做到这一点在一个单一的查询,但我们可以得到它在两个查询:

 要求'active_record

ActiveRecord的:: Base.establish_connection适配器:sqlite3的',数据库:':内存:'

的ActiveRecord :: Schema.define做
  self.verbose = FALSE
  CREATE_TABLE:位置做| T |
    t.integer:数量
    t.integer:market_​​price
  结束
结束

一流的位置和LT;的ActiveRecord :: Base的
  高清self.with_market_​​value
    选择 *,
            数量* market_​​price为market_​​value,
            数量* market_​​price /#{total.to_f}为百分比
  结束

  高清self.total
    选择(总和(数量* market_​​price)为sum_of_market_​​values​​)。first.sum_of_market_​​values
  结束
结束

Position.create!数量:25,market_​​price:4
Position.create!数量:25,market_​​price:4
Position.create!数量:25,market_​​price:4
Position.create!数量:25,market_​​price:4
Position.create!数量:25,market_​​price:4
Position.create!数量:25,market_​​price:20

Position.with_market_​​value.map {| P | [p.market_​​value,p.percent]}
#=> [[100,0.1],[100,0.1],[100,0.1],[100,0.1],[100,0.1],[500,0.5]]

Position.where('market_​​price小于10')with_market_​​value.map {| P |。 [p.market_​​value,p.percent]}
#=> [[100,0.2],[100,0.2],[100,0.2],[100,0.2],[100,0.2]]

#**注意,执行热切**
Position.with_market_​​value.where('market_​​price小于10')地图{| P |。 [p.market_​​value,p.percent]}
#=> [[100,0.1],[100,0.1],[100,0.1],[100,0.1],[100,0.1]]
 

Create a scope, maybe something like this..

scope :mv, select('*,quantity*market_price as market_value, quantity*market_price/sum(quantity*market_price) as percent')

that creates two virtual attributes, market_value and percent. The problem I am having is creating the percent with the sum() included. If I add sum(), the scope returns one record.

I need to calculate the percent of market_value relative to the total market value of the scoped record set.

example:

1, market_value: 100, percent: .10
2, market_value: 100, percent: .10
3, market_value: 100, percent: .10
4, market_value: 100, percent: .10
5, market_value: 100, percent: .10
6, market_value: 500, percent: .50
Total is 1000

however, if I scope it to where market_value < 6, I should see

1, market_value: 100, percent: .20
2, market_value: 100, percent: .20
3, market_value: 100, percent: .20
4, market_value: 100, percent: .20
5, market_value: 100, percent: .20
Total 500

How can I accomplish this?

I created a self.pct method but problem with the self.pct method is that it needs to be run after all the scopes. if rescoped, the solution is wrong

So far,

class Position < ActiveRecord::Base
  attr_accessible :account_id, :account_type, :market_price, :quantity, :report_date, :symbol

  scope :long_only, where(:account_type => 'L')
  scope :short_only, where(:account_type=>"S")
  scope :equity_only, :conditions => ["symbol <> 'USD'"]

 scope :mv, select('*,quantity*market_price as market_value, quantity*market_price/sum(quantity*market_price) as percent')

 scope :mv1, lambda{|total| select(total) }

  #the problem with the self.pct method is that it needs to be run after all the scopes. if rescoped, the solution is wrong

 def self.pct 
   string="*,(quantity*market_price) as market_value, (market_price*quantity/#{sum_market_value}) as percent"
   mv1(string)
 end


  def market_value
    self.market_price*self.quantity
  end


  def self.sum_market_value
    sum('quantity*market_price')
  end
end

解决方案

I don't know if there's a way to do this in a single query, but we can get it in two queries:

require 'active_record'

ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'

ActiveRecord::Schema.define do
  self.verbose = false
  create_table :positions do |t|
    t.integer :quantity
    t.integer :market_price
  end
end

class Position < ActiveRecord::Base
  def self.with_market_value
    select "*, 
            quantity*market_price as market_value,
            quantity*market_price/#{total.to_f} as percent"
  end

  def self.total
    select('sum(quantity*market_price) as sum_of_market_values').first.sum_of_market_values
  end
end

Position.create! quantity: 25, market_price: 4
Position.create! quantity: 25, market_price: 4
Position.create! quantity: 25, market_price: 4
Position.create! quantity: 25, market_price: 4
Position.create! quantity: 25, market_price: 4
Position.create! quantity: 25, market_price: 20

Position.with_market_value.map { |p| [p.market_value, p.percent] }
# => [[100, 0.1], [100, 0.1], [100, 0.1], [100, 0.1], [100, 0.1], [500, 0.5]]

Position.where('market_price < 10').with_market_value.map { |p| [p.market_value, p.percent] }
# => [[100, 0.2], [100, 0.2], [100, 0.2], [100, 0.2], [100, 0.2]]

# ** NOTE THAT IT EXECUTES EAGERLY **
Position.with_market_value.where('market_price < 10').map { |p| [p.market_value, p.percent] }
# => [[100, 0.1], [100, 0.1], [100, 0.1], [100, 0.1], [100, 0.1]]

这篇关于计算总的百分比从范围记录和显示虚拟属性(轨道/活动记录)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆