【问题标题】:Calculate Percent of total from scoped records and display virtual attributes (Rails / Active Record)计算范围记录的总数百分比并显示虚拟属性(Rails / Active Record)
【发布时间】:2013-06-20 19:39:17
【问题描述】:

创建一个范围,可能是这样的..

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

创建两个虚拟属性,market_value 和 percent。我遇到的问题是创建包含 sum() 的百分比。如果我添加 sum(),则作用域返回一条记录。

我需要计算 market_value 相对于范围记录集的总市值的百分比。

示例:

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

但是,如果我将其范围限定为 market_value

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

我怎样才能做到这一点?

我创建了一个 self.pct 方法,但 self.pct 方法的问题是它需要在所有作用域之后运行。如果重新调整范围,则解决方案是错误的

到目前为止,

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

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord rails-models


    【解决方案1】:

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

    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]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 2012-09-08
      • 2016-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      相关资源
      最近更新 更多