在 Rails 3 中创建哈希

发布于 2024-11-09 08:27:49 字数 4991 浏览 4 评论 0原文

我掌握了一种计算 ISBN 版税的方法。它按销售渠道划分销售额。特许权使用费率由销售总量决定,特许权使用费的计算方法是特许权使用费率(百分比)乘以总收入。因此,结果应该是每个 ISBN 的每个销售渠道的计算版税数字。原谅可能被过度注释的代码。

在 isbns_controller 的 show 方法中:

@isbn = Isbn.find(params[:id])

def royalty(isbn)
  @royaltiesbychannel = Hash.new()     
  # Returns all sales for the current isbn, and groups them by channel_id in a hash 
  # {1 => sale 1, sale 2}, {2 => sale 1, sale 2}
  # Then loops through each key-value pair.    
  @isbn.sales.group_by(&:channel_id).each do |ch_id, sale_array|
    # Takes the sales grouped by channel, and totals the quantities and values into two separate variables. 
    value_total_by_channel = sale_array.sum(&:value)  
    quantity_total_by_channel = sale_array.sum(&:quantity)  
     # Gets all the rules for the isbn
     @isbn.rules.each do |rule|
       # Jumps to the next sales hash unless the channel ids match
       next unless rule.channel_id == ch_id
       if Range.new(rule.lower,rule.upper).include?(quantity_total_by_channel)
         @royaltiesbychannel[ch_id] = value_total_by_channel * rule.rate
       end
     end
   end
 end

最后一行给我带来了问题。我想要的是生成一个哈希值,其中通道 ID 作为键,计算出的版税作为值。但相反,它只生成一个只有一个键值对的散列,看起来像这样:

{1=>#<BigDecimal:10132a620,'0.875E5',9(36)>}

我怀疑我在方法顶部创建新散列的方式有问题,并且尝试声明方括号中的键。

rule.rate 是用小数表示的百分比,例如 0.10。该值是一个整数(至少目前是这样)。关于如何生成这个哈希有什么想法吗?

其次,迭代视图中生成的哈希值的最佳方法是什么?

非常感谢。

更新 - 按要求输出 .inspect:

{1=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], 2=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

第二次更新:对问题的修订:

感谢您到目前为止的想法。事实证明,该方法运行良好,因为 @isbn.sales.group_by(&:channel_id) 生成的哈希仅包含一个键值对。所以我的问题仍然存在,但对于我的代码的不同部分:如何在 Sales 模型上执行查找以生成像 {1 =>;销售 1,销售 2},{2 =>销售 1,销售 2}

我已经尝试过这个可怕的事情:

@channelarray = Channel.select(:id).all  
@salesbychannelwrong = @channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}   
@salesbychannel = @salesbychannelwrong.invert

这给出了这个:

{[#<Channel id: 1>]=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], [#<Channel id: 2>]=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

我也尝试过

Sale.find_by_isbn_id(:id).group_by(&:channel_id)

返回nil

并且

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id)

返回

undefined method `group_by' for #<Sale:0x0000010122df60>

我有以下模型:

class Sale
  belongs_to :isbn
  belongs_to :channel
  ...
end

class Isbn
  has_many :rules
  has_many :sales
  has_many :channels, :through => :sales
  ...
end

class Channel
  has_many :sales
  has_many :rules
  ...
end

class Rule
  belongs_to :isbn
  belongs_to :channel
  has_many :sales, :through => :isbn
  ...
end

再次感谢。

I have the makings of a method which calculates royalties for ISBNs. It splits sales by sales channel. The royalty rate is determined by the total quantity sold, and the royalty is calculated by multiplying the royalty rate (a percentage) by the total revenue. So the result should be a calculated royalty figure for each sales channel, for each isbn. Forgive what is probably over-commented code.

In the show method of the isbns_controller:

@isbn = Isbn.find(params[:id])

def royalty(isbn)
  @royaltiesbychannel = Hash.new()     
  # Returns all sales for the current isbn, and groups them by channel_id in a hash 
  # {1 => sale 1, sale 2}, {2 => sale 1, sale 2}
  # Then loops through each key-value pair.    
  @isbn.sales.group_by(&:channel_id).each do |ch_id, sale_array|
    # Takes the sales grouped by channel, and totals the quantities and values into two separate variables. 
    value_total_by_channel = sale_array.sum(&:value)  
    quantity_total_by_channel = sale_array.sum(&:quantity)  
     # Gets all the rules for the isbn
     @isbn.rules.each do |rule|
       # Jumps to the next sales hash unless the channel ids match
       next unless rule.channel_id == ch_id
       if Range.new(rule.lower,rule.upper).include?(quantity_total_by_channel)
         @royaltiesbychannel[ch_id] = value_total_by_channel * rule.rate
       end
     end
   end
 end

It's that last line which is giving me a problem. What I want is to produce a hash with the channel ids as the keys, and the calculated royalties as the values. But instead, it's producing a hash with just one key-value pair, in something which looks like this:

{1=>#<BigDecimal:10132a620,'0.875E5',9(36)>}

I suspect there's something wrong with the way I'm creating a new hash at the top of the method, and also with trying to declare the key in the square brackets.

The rule.rate is a percentage expressed as a decimal, e.g. 0.10. The value is an integer (at the moment, at least). Any thoughts on how to generate this hash?

Secondly, what's the best way to iterate through the resultant hash in the view?

Many thanks in advance.

Update - output of .inspect as requested:

{1=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], 2=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

Second update: revision to the question:

Thanks for your thoughts so far. It turns out the method is working fine, because the hash generated by @isbn.sales.group_by(&:channel_id) only contains one key-value pair. So my question still stands, but for a different bit of my code: how do I perform a find on the Sales model to produce an array of hashes like {1 => sale 1, sale 2}, {2 => sale 1, sale 2}?

I have tried this horrible thing:

@channelarray = Channel.select(:id).all  
@salesbychannelwrong = @channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}   
@salesbychannel = @salesbychannelwrong.invert

which gives this:

{[#<Channel id: 1>]=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], [#<Channel id: 2>]=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

I have also tried

Sale.find_by_isbn_id(:id).group_by(&:channel_id)

which returns nil

and this

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id)

which returns

undefined method `group_by' for #<Sale:0x0000010122df60>

I have the following models:

class Sale
  belongs_to :isbn
  belongs_to :channel
  ...
end

class Isbn
  has_many :rules
  has_many :sales
  has_many :channels, :through => :sales
  ...
end

class Channel
  has_many :sales
  has_many :rules
  ...
end

class Rule
  belongs_to :isbn
  belongs_to :channel
  has_many :sales, :through => :isbn
  ...
end

Thanks again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千仐 2024-11-16 08:27:49

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id) =>; Sale.find_all_by_isbn_id(@isbn).group_by(&:channel_id)

Sale.where(:ibn_id => @isbn.id).group_by(&:channel_id)

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id) => Sale.find_all_by_isbn_id(@isbn).group_by(&:channel_id)

or

Sale.where(:ibn_id => @isbn.id).group_by(&:channel_id)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文