Rails 3:使用数组的内容作为 where 方法中的变量

发布于 2024-11-06 03:48:02 字数 3442 浏览 0 评论 0原文

我有三个模型:Isbn、Sale 和 Channel。

目标:在 isbns show.html.erb 视图中获取如下所示的列表:

Isbn: myisbn

myisbn 的总销售额:100

渠道 1 的 Myisbn 销售额:50

渠道 2 的 Myisbn 销售额:25

渠道 3 的 Myisbn 销售额: 25

这是我的模型。 Isbn.rb 模型

has_many :sales
has_many :channels, :through => :sales

Sale.rb 模型(具有属性 sales_channel_id、isbn_id、数量)

has_many :channels
belongs_to :isbn

Channel.rb 模型:

belongs_to :sale

我一直在 isbns 控制器的 show 方法中工作,只是为了让某些东西发挥作用。我想我稍后会重构 - 关于这些东西是否应该放入模型中的建议将是最受欢迎的。

到目前为止,我已经得到了:

@channelisbn = Sale.where("sales_channel_id =?',1).where("isbn_id=?",3)
@channelsalesisbn = 0
@channelisbn.each {|y| @channelsalesisbn =+ y.quantity}

这成功地获取了频道 ID 为 1 且 ISBN id 为 3 的所有销售。但这没有多大用处,因为 ID 是硬编码的。所以我将通道 ID 放入一个数组中:

@channellist = Channel.all
@channel = 0
@channelarray = @channellist.map {|z| @channel = z.id}

这给了我一个可爱的 [1,2,3,4] 数组

,但我不知道如何传递 1,然后是 2,然后是 3,然后是 4到一个块中,该块可用于查找具有该销售渠道 ID 的 ISBN 销售。这就是我尝试过的(仍然对 ISBN id 进行硬编码 - 以为我会一次解决一个问题),它返回一个空数组:

@channelarray.each do |channel|
 @channelisbn = []
 @channelisbn = Sale.where("sales_channel_id = ?", channel).where("isbn_id = ?",3)
 @channelsalesisbn = 0
 @result = []
 @result << @channelisbn.each {|a| @channelsalesisbn =+ a.quantity}
end

然后我将对数组的内容求和。

任何帮助将不胜感激。这是我的第一篇文章,所以我的零接受率很快就会改变!

更新

为了结束这个问题,这就是我最终的结果,这很棒,并且准备好进行修改:一个数组,很好地分组,按渠道给我提供了 isbn 的销售额。感谢 group_by 的提示!

#in the show action in the isbns controller:

@isbn = Isbn.find(params[:id])
@channelarray = Channel.select(:id).all   
@channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}

在控制台中,为了清晰起见,添加了换行符:(

首先偷偷地设置@isbn = 3,因为在控制台中你无法从视图传递参数,所以控制器中定义的@isbn实例在控制台中为零)

ruby-1.9.2-p180 :067 > @channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}

=> {[#<Sale id: 1, isbn_id: 3, quantity: 10000, value: 12000, currency: "GBP", total_quantity: nil, created_at: "2011-05-06 12:30:35", updated_at: "2011-05-07 17:43:13", customer: "Waterstone's", retail_price: nil, discount: nil, invoice_date: "2011-05-24">, #<Sale id: 2, isbn_id: 3, quantity: 1000, value: 500, currency: "GBP", total_quantity: nil, created_at: "2011-05-07 09:37:53", updated_at: "2011-05-07 19:14:52", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-02-05">]=>[#<Channel id: 1>], 

[#<Sale id: 3, isbn_id: 3, quantity: 500, value: 1500, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:11", updated_at: "2011-05-07 19:15:07", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-12-05">, #<Sale id: 4, isbn_id: 3, quantity: 45, value: 300, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:38", updated_at: "2011-05-07 19:15:36", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-06-05">]=>[#<Channel id: 2>], 

[]=>[#<Channel id: 3>], 

[]=>[#<Channel id: 4>]} 

更新2

哈,我生成的散列的键值对是错误的。包含销售数据的数组是键 - 它应该是值。 Rubydocs 挽救了局面:

@salesbychannel = @salesbychannelwrong.invert

invert 方法切换键值对。甜的。

I have three models: Isbn, Sale and Channel.

Aim: to get a list in the isbns show.html.erb view which looks something like this:

Isbn: myisbn

Total sales for myisbn: 100

Myisbn sales for channel 1: 50

Myisbn sales for channel 2: 25

Myisbn sales for channel 3: 25

Here are my models.
Isbn.rb model

has_many :sales
has_many :channels, :through => :sales

Sale.rb model (has attributes sales_channel_id, isbn_id, quantity)

has_many :channels
belongs_to :isbn

Channel.rb model:

belongs_to :sale

I've been working in the isbns controller, in the show method, just to get something to work. I thought I'd refactor later - advice on whether any of this stuff should go in the model would be most welcome.

So far I've got this:

@channelisbn = Sale.where("sales_channel_id =?',1).where("isbn_id=?",3)
@channelsalesisbn = 0
@channelisbn.each {|y| @channelsalesisbn =+ y.quantity}

This successfully gets all the sales where Channel ID is 1 and ISBN id is 3. But it's not much use, as the IDs are hard coded. So I got the Channel IDs into an array:

@channellist = Channel.all
@channel = 0
@channelarray = @channellist.map {|z| @channel = z.id}

which gives me a lovely array of [1,2,3,4]

But I can't figure out how to pass the 1, then the 2, then the 3 and then the 4 into a block which can be used to look up an ISBN's sales which have that sales channel id. This is what I tried (still hardcoding the ISBN id - thought I'd tackle one problem at a time), which returned an empty array:

@channelarray.each do |channel|
 @channelisbn = []
 @channelisbn = Sale.where("sales_channel_id = ?", channel).where("isbn_id = ?",3)
 @channelsalesisbn = 0
 @result = []
 @result << @channelisbn.each {|a| @channelsalesisbn =+ a.quantity}
end

I was then going to sum the contents of the array.

Any help would be gratefully received. This is my first post, so my zero acceptance rate will change soon!

UPDATE

Just to finish this question off, here's where I've ended up, which is great, and ready for tinkering with: an array, nicely grouped, giving me sales by isbn by channel. Thanks for the group_by tip off!

#in the show action in the isbns controller:

@isbn = Isbn.find(params[:id])
@channelarray = Channel.select(:id).all   
@channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}

From the console, line breaks added for clarity:

(sneakily set @isbn = 3 first of all, since in the console you can't pass params from a view, so the @isbn instance defined in the controller is nil in the console)

ruby-1.9.2-p180 :067 > @channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}

=> {[#<Sale id: 1, isbn_id: 3, quantity: 10000, value: 12000, currency: "GBP", total_quantity: nil, created_at: "2011-05-06 12:30:35", updated_at: "2011-05-07 17:43:13", customer: "Waterstone's", retail_price: nil, discount: nil, invoice_date: "2011-05-24">, #<Sale id: 2, isbn_id: 3, quantity: 1000, value: 500, currency: "GBP", total_quantity: nil, created_at: "2011-05-07 09:37:53", updated_at: "2011-05-07 19:14:52", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-02-05">]=>[#<Channel id: 1>], 

[#<Sale id: 3, isbn_id: 3, quantity: 500, value: 1500, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:11", updated_at: "2011-05-07 19:15:07", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-12-05">, #<Sale id: 4, isbn_id: 3, quantity: 45, value: 300, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:38", updated_at: "2011-05-07 19:15:36", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-06-05">]=>[#<Channel id: 2>], 

[]=>[#<Channel id: 3>], 

[]=>[#<Channel id: 4>]} 

UPDATE 2

Ha, the hash I generated had the key value pairs the wrong way round. The array containing the sales data was the key - it should have been the value. Rubydocs saved the day:

@salesbychannel = @salesbychannelwrong.invert

The invert method switches the key-value pairs. Sweet.

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

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

发布评论

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

评论(1

蒲公英的约定 2024-11-13 03:48:02

您正在寻找的是将数组传递给 ARel#where(),如下所示:

Sale.where(:sales_channel_id => @channelarray)

这应该执行 IN 查询。如果这不起作用,您可以随时将数组传递给 ActiveRecord#find,如下所示:

Sale.find(@channelarray)

希望这有帮助

What you're looking for is passing an array to a ARel#where(), like this:

Sale.where(:sales_channel_id => @channelarray)

This should execute an IN query. If that's not working, you can always pass the array to ActiveRecord#find, like this:

Sale.find(@channelarray)

Hope this helps

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