问题
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