ruby对象数组...或哈希

hol*_*den 2 ruby arrays methods ruby-on-rails class

我现在有一个对象:

class Items
  attr_accessor :item_id, :name, :description, :rating

  def initialize(options = {})
      options.each {
        |k,v|
        self.send( "#{k.to_s}=".intern, v)
      }
  end

end
Run Code Online (Sandbox Code Playgroud)

我把它作为单个对象分配到一个数组中......

@result = []

some loop>>
   @result << Items.new(options[:name] => 'name', options[:description] => 'blah')
end loop>>
Run Code Online (Sandbox Code Playgroud)

但不是将我的单个对象分配给数组......我怎样才能使对象本身成为一个集合?

基本上想要以这样的方式拥有对象,以便我可以定义诸如的方法

def self.names
   @items.each do |item|
      item.name
   end
end
Run Code Online (Sandbox Code Playgroud)

我希望这是有道理的,可能我忽视了一些宏伟的计划,这将使我的生活在两行中变得无比轻松.

tad*_*man 6

在我发布一个如何重做的例子之前的一些观察.

  • 给一个复数名称的类在声明新对象时可能会导致很多语义问题,因为在这种情况下你会调用Items.new,这意味着你实际创建了几个项目.对单个实体使用单数形式.
  • 调用任意方法时要小心,因为你会在任何未命中时抛出异常.要么检查你是否可以先打电话给他们,或者从适用的不可避免的灾难中解救出来.

解决问题的一种方法是专门为Item对象创建一个自定义集合类,它可以为您提供名称等所需的信息.例如:

class Item
  attr_accessor :item_id, :name, :description, :rating

  def initialize(options = { })
    options.each do |k,v|
      method = :"#{k}="

      # Check that the method call is valid before making it
      if (respond_to?(method))
        self.send(method, v)
      else
        # If not, produce a meaningful error
        raise "Unknown attribute #{k}"
      end
    end
  end
end

class ItemsCollection < Array
  # This collection does everything an Array does, plus
  # you can add utility methods like names.

  def names
    collect do |i|
      i.name
    end
  end
end

# Example

# Create a custom collection
items = ItemsCollection.new

# Build a few basic examples
[
  {
    :item_id => 1,
    :name => 'Fastball',
    :description => 'Faster than a slowball',
    :rating => 2
  },
  {
    :item_id => 2,
    :name => 'Jack of Nines',
    :description => 'Hypothetical playing card',
    :rating => 3
  },
  {
    :item_id => 3,
    :name => 'Ruby Book',
    :description => 'A book made entirely of precious gems',
    :rating => 1
  }
].each do |example|
  items << Item.new(example)
end

puts items.names.join(', ')
# => Fastball, Jack of Nines, Ruby Book
Run Code Online (Sandbox Code Playgroud)