Ruby project help. Can't get saved instances from array

谁都会走 提交于 2021-02-17 06:43:25

问题


TLDR I am working on a project that creates instances using an API. I want to be able to recall all of my instances but can't figure out how. I'm relatively new to Ruby and programming in general so I hope I'm explaining everything well enough. Here's my code.

class Suggestion
    attr_accessor :type, :participants 
    attr_reader :activity, :price, :link, :key, :accessibility

    @@all = []

    def initialize(type, participants)
        @type = type
        @participants = participants
        # @activity = []
        # @price = price
        # @key = key
        # @accessibility = accessibility
         @@all << self
    end

    # def save
    #     @@all << self
    # end

    def self.all
        @@all
    end

    # def events
    #     @@all.map
    # end
    
    def list_events
        # binding.pry
        Suggestion.all.map #{|event| [:activity, :type, :participants, :price, :link, :key, :accessibility]}
    end

end

any and all help would be greatly appreciated


回答1:


What Already Works

I may be misunderstanding your issue, but it seems like your code mostly works as-is. I refactored it a little to make it a little easier to see what's going on, but your basic approach of self-registration with a class variable during object initialization seems sound. Consider:

class Suggestion
  @@all = []

  def initialize(type, participants)
      @type = type
      @participants = participants
      @@all << self
  end 

  def self.all
      @@all
  end 
end
s1 = Suggestion.new :foo, %w[Alice Bob]
#=> #<Suggestion:0x00007f9671154578 @participants=["Alice", "Bob"], @type=:foo>

s2 = Suggestion.new :bar, %w[Charlie Dana]
#=> #<Suggestion:0x00007faed7113900 @participants=:bar, @type=:foo>

Suggestion.all
#=>
[#<Suggestion:0x00007f9671154578 @participants=["Alice", "Bob"], @type=:foo>,
 #<Suggestion:0x00007f9671089058
  @participants=["Charlie", "Dana"],
  @type=:bar>]

What Might Need Improvement

You probably just need class or instance methods that "do a thing" with each instance (or selected elements from specific instances) stored in @@all. For example:

# print the object ID of each instance of Suggestion
Suggestion.all.map { |suggestion| suggestion.object_id }
#=> [240, 260]

You might also want to use Array#select to extract specific instances that meet defined criteria, or Array#map to do something with your matching instances. For example:

# re-open the class to add some getter methods
class Suggestion
  attr_reader :type, :participants
end

# only operate on instances of a given type
Suggestion.all.select { |s| s.type == :foo }
#=> [#<Suggestion:0x00007f9671154578 @participants=["Alice", "Bob"], @type=:foo>]

# invoke Suggestion#participants on matching instances
Suggestion.all.map { |s| s.participants if s.type == :bar }.compact
#=> [["Charlie", "Dana"]]

As long as you have a collection through which you can iterate (e.g. your class' @@all Array) you can filter, map, or otherwise operate on some or all of your instances at need. There are certainly more complex approaches, but I'd strive to keep it as simple as possible.




回答2:


Consider the following class definition, where I've made @all a class instance variable, rather than a class variable. Use of the former is generally preferred over use of the latter.

class Suggestion
  attr_accessor :type, :participants

  @all = []

  class << self
    attr_accessor :all
  end

  def initialize(type, participants)
    @type = type
    @participants = participants
    self.class.all << self
  end 

  def list_events
    self.class.all.map do |instance|
      { type: instance.type, participants: instance.participants }
    end 
  end

  def self.list_events
    all.map do |instance|
      { type: instance.type, participants: instance.participants }
    end 
  end
end

The snippet

class << self
  attr_accessor :all
end

creates a read-write accessor for @all. class << self causes self to be changed to Suggestion's singleton class. If desired you could replace this with

superclass.public_send(:attr_accessor, :all)

Let's try it.

Suggestion.all
  #=> []
s1 = Suggestion.new(1, ['Bob', 'Sally'])
  #=> #<Suggestion:0x00007fc677084888 @type=1, @participants=["Bob", "Sally"]>
Suggestion.all
  #=> [#<Suggestion:0x00007fc677084888 @type=1, @participants=["Bob", "Sally"]>]
s2 = Suggestion.new(2, ['Ronda', 'Cliff'])
  #<Suggestion:0x00007fc677b577b0 @type=2, @participants=["Ronda", "Cliff"]>
Suggestion.all
  #=> [#<Suggestion:0x00007fc677084888 @type=1, @participants=["Bob", "Sally"]>,
  #    #<Suggestion:0x00007fc677b577b0 @type=2, @participants=["Ronda", "Cliff"]>]
s3 = Suggestion.new(3, ['Weasel', 'Isobel'])
  #=> #<Suggestion:0x00007fc677077598 @type=3, @participants=["Weasel", "Isobel"]>
Suggestion.all
  #=> [#<Suggestion:0x00007fc677084888 @type=1, @participants=["Bob", "Sally"]>,
  #    #<Suggestion:0x00007fc677b577b0 @type=2, @participants=["Ronda", "Cliff"]>,
  #    #<Suggestion:0x00007fc677077598 @type=3, @participants=["Weasel", "Isobel"]>]
s1.list_events
  #=> [{:type=>1, :participants=>["Bob", "Sally"]},
  #    {:type=>2, :participants=>["Ronda", "Cliff"]},
  #    {:type=>3, :participants=>["Weasel", "Isobel"]}]
Suggestion.list_events
  #=> [{:type=>1, :participants=>["Bob", "Sally"]},
  #    {:type=>2, :participants=>["Ronda", "Cliff"]},
  #    {:type=>3, :participants=>["Weasel", "Isobel"]}]

I included Suggestion#instance to show how an instance can access (read or write) the class instance variable @all.



来源:https://stackoverflow.com/questions/66093842/ruby-project-help-cant-get-saved-instances-from-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!