Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何改进这段代码_Ruby On Rails_Ruby_Activerecord_Enumerator - Fatal编程技术网

Ruby on rails 如何改进这段代码

Ruby on rails 如何改进这段代码,ruby-on-rails,ruby,activerecord,enumerator,Ruby On Rails,Ruby,Activerecord,Enumerator,我正在经营一家在线手袋商店,手袋可以有四种颜色——黑色、棕色、橙色和红色。我注意到黑色手提包比棕色手提包卖得快,诸如此类。这意味着人们最喜欢黑色手提包 在网上商店的主页上,我想选择并以网格布局显示10个包。所以我从选择黑色袋子开始。如果我的库存中有10个或更多的黑色袋子,那么我会停下来,不再寻找其他颜色的袋子。然而,如果我有5个黑色的袋子,那么我会继续寻找棕色的袋子。在添加那些棕色的袋子之后,如果我仍然没有10个袋子,那么我会寻找橙色的袋子等等 以下是我将解决方案实现为Rails模型方法的尝试:

我正在经营一家在线手袋商店,手袋可以有四种颜色——黑色、棕色、橙色和红色。我注意到黑色手提包比棕色手提包卖得快,诸如此类。这意味着人们最喜欢黑色手提包

在网上商店的主页上,我想选择并以网格布局显示10个包。所以我从选择黑色袋子开始。如果我的库存中有10个或更多的黑色袋子,那么我会停下来,不再寻找其他颜色的袋子。然而,如果我有5个黑色的袋子,那么我会继续寻找棕色的袋子。在添加那些棕色的袋子之后,如果我仍然没有10个袋子,那么我会寻找橙色的袋子等等

以下是我将解决方案实现为Rails模型方法的尝试:

class Handbag < ActiveRecord::Base
  belongs_to :store
  attr_accessor :color
end

class Store < ActiveRecord::Base
  has_many :handbags

  def handags_for_display
    selected_handbags = []
    ["black", "brown", "orange", "red"].each do |color|
      bags = get_handbags_by_color(color)
      selected_bags += bags
      if selected_bags.size >= 10
        selected_handbags = selected_handbags[0..9]
        break
      end
    end
    selected_handbags
  end

  private
  def get_handbags_by_color(color)
    handbags.where("color = ?", color).limit(10)
  end
end
class手提包=10
选定的_手提包=选定的_手提包[0..9]
打破
终止
终止
精选手提包
终止
私有的
def按颜色获取手提包(颜色)
手提包。其中(“颜色=?”,颜色)。限制(10)
终止
终止

虽然这是可行的,但我很好奇是否有更好的方法来写它。特别是,我认为这段代码可以转换为使用Ruby的枚举器。

您应该立即查询数据库,执行如下操作:

@page_offset = ((params[:page].to_i-1)*10) || 0
Handbag.order("color ASC").limit(10).offset(@page_offset)

幸运的是,颜色已经按字母顺序排列。

您可以尝试这样的递归函数。这就像预期的那样工作(运行它将为您提供
{:black=>1,:brown=>8,:orange=>1}
),您只需更改get\u手提包的颜色即可使用Rails

def handags_for_display
     handbags = Array.new
     [{ :color => 'black', :count => 5 }, { :color => 'brown' , :count => 2 }, { :color => 'orange', :count => 1 }, { :color => 'red', :count => 1}].each do |handbag|
          handbags+=Handbag.where("color = ?", handbag[:color]).limit(handbag[:count])
     end
     handbags
end
@bags = {
  :black => 1,
  :brown => 8,
  :orange => 10,
  :red => 10
}

@handbag_order = [:black, :brown, :orange, :red]
@max_bags = 10

def get_handbags_by_color(color,limit)
  num = @bags[color]
  num > limit ? limit : num
end

def handbags_for_display(index = 0, total = 0)
  color = @handbag_order[index]
  return {} unless color
  handbags = {color => get_handbags_by_color(color,@max_bags - total)}
  total += handbags.values.inject{|sum,x| sum+x}

  handbags.merge!(handbags_for_display(index+1, total)) unless(total >= @max_bags)
  handbags
end

handbags = handbags_for_display

这对我来说是一个更好的问题。它已经被修正以适应那个案例。另外,无论是谁投票否决了我,请解释为什么。@Dex您的解决方案工作正常。在使用模型时,我必须习惯于更多地考虑SQL而不是Ruby。顺便说一句,没有必要分页,因为我从来不会显示超过10个手提包。只是为了区分接受的答案,这一个将允许您随时更改顺序,轻松更改限制,并且只运行尽可能多的查询以达到限制