Ruby/Rails - Add records to an object with each loop iteration / Object vs Arrays
I'm trying to figure out how to add records to an existing object for each iteration of a loop. I'm having a hard time discovering the difference between an object and an array.
I have this
@events = Event.find(1)
@loops = Choices.find(:all, :limit => 5) #so loop for 5 instances of choice model
for loop in @loops
@events = Event.find(:all,:conditions => ["event.id = ?", loop.event_id ])
end
I'm trying to add a new events to the existing @events object based on the id of whatever the loop variable is. But the ( = ) operator just creates a new instance of the @events object.
I tried ( += ) and ( << ) as operators but got the error
"You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil"
I tried created an array
events = []
events << Event.find(1)
@loops = Choices.find(:all, :limit => 5) #so loop for 5 instances of choice model
for loop in @loops
events << Event.find(:all,:conditions => ["event.id = ?", loop.event_id ])
end
But I dont know how to call that arrays attributes within the view
With objects I was able do create a loop within the view and call all the attributes of that object as well...
<table>
<% for event in @events %>
<tr>
<td><%= link_to event.title, event %></td>
<开发者_开发知识库;td><%= event.start_date %></td>
<td><%= event.price %></td>
</tr>
<% end %>
</table>
How could i do this with an array set?
So the questions are
1) Whats the difference between arrays and objects?
2) Is there a way to add into the existing object for each iteration? 3) If I use an array, is there a way to call the attributes for each array record within the view?@events = []
@events << Event.find(1)
@loops = Choices.find(:all, :limit => 5)
for loop in @loops
es = Event.find(:all, :conditions => ["event.id = ?", loop.event_id])
for e in es
@events << e
end
end
First, take a step back. Let's figure out exactly what you're trying to do.
To me, it seems like: Find all of the events referenced by the first five choices.
If this is all you are trying to do, save yourself some time and queries by writing:
@choices = Choices.limit(5).include(:event)
This assumes there's a has_{one,many}
/belongs_to
association between the two, which there should be, I think. Though the class names are vague enough that I may be missing something.
You can then loop through @choices
and pull out the event
associated with it. Or use something like Enumerable#collect
You can tack on Event.find(1)
to the array this produces by using Array#push or Array#<<.
We have to guess because there is no detailed information about the models and their relations. But Assuming that a choice has_many events I'd do (add an include of events if you care for efficiency):
@events = [Event.find(1)] + Choice.all(:limit => 5).map(&:events).flatten
This should also work even if you don't have Rails associations, though it looks uglier (isn't ActiveRecord's find a bit promiscous on what accepts as arguments?):
@events = Event.find(1, Choice.all(:limit => 5).map(&:event_id))
In JavaScript, there is an Object that stores key-value pairs (similar to a Hash in Ruby) and there is an Array (which stores an ordered set of values). In JavaScript, Arrays (as with all objects) can have arbitrary properties added at any time. This causes some confusion between Object and Array in JavaScript. In Ruby, this is not the case.
- In Ruby,
Object
is the base class from which all other objects inherit. You can read the documentation for Object here. - In Ruby,
Array
is a class for storing an ordered list of values. You can read the documentation for Array here. - In Ruby, just about everything is an "object", insofar as it has methods.
Instead of "Object", though, I think perhaps you mean "instance variable". Instance variables are prefixed with an 'at' sign, e.g.
@foo
. Variables are not themselves objects, nor do they contain objects; rather, they point to (or reference) objects. The objects that they reference may be of many different types.- In Ruby,
@Justice has shown you one way to add items to an array inside a loop.
If you have an instance variable that is an array, you can iterate over its values inside the view. The syntax for this depends on what template system you are using (Erb, Haml, etc.)
If you are using Rails 3, you can do this:
loops = [1] + Choice.select("event_id").limit(5).collect {|x| x.event_id}
@events = Event.all(:conditions => ["id in (?)", loops])
This will collect all of the event_id's from choices into an array, appended to the event id 1, that can then be used in the IN clause of the Event.all query. This should be more efficient than looping through your choices and generating queries for each one.
精彩评论