-
Notifications
You must be signed in to change notification settings - Fork 48
Home
If you have have a general question that is not specific to the Module 2 content, it may have already been answered here.
Course 3 Module 1 FAQs are here
- Q: How to correctly use find with aggregation framework
- Q: How could a method accept different types of optional parameters and apply them accordingly?
- Q: Why do I get thr error "uninitialized constant"?
- Q: On assignment places collection (3) and (4), I don't understand "Implement a custom type"?
The following query is not working for me:
Photo.find_photos_for_place(@id).aggregate([
{:$skip=> offset},
{:$limit=> limit}
]).each {|doc| photos << Photo.new(doc)}
A: This query is mixing regular find with aggregation framework. That will not work. The find()
is not executed and only what you placed in the aggregate pipeline will execute. Use
.skip(#)
.limit(#)
on the result from Photo.find_photos_for_place. Example
def photos(offset=0, limit=nil)
view=Photo.find_photos_for_place
view.skip(offset)
view.limit(limit) if limit
view.map {|r| ... }
Let's go through step by step:
> Photo.find_photos_for_place(place.id).class
=> Mongo::Collection::View
A View. The query has not executed yet.
> Photo.find_photos_for_place(place.id).first
places_development.find | STARTED | {"find"=>"fs.files", "filter"=>{:"metadata.place"=>BSON::ObjectId('56d8f925e301d0390200000c')}}
=> {"_id"=>BSON::ObjectId('56d...
A result. The query has executed.
> Photo.find_photos_for_place(place.id).aggregate([])
(no query)
> Photo.find_photos_for_place(place.id).aggregate([]).class
=> Mongo::Collection::View::Aggregation
Attempting to append aggregate commands to find does not execute the find. It returns a View::Aggregation
> Photo.find_photos_for_place(place.id).aggregate([]).to_a
places_development.aggregate | STARTED |
{"aggregate"=>"fs.files", "pipeline"=>[], "cursor"=>{}}
=> 6
> Photo.find_photos_for_place(place.id).to_a.count
places_development.find | STARTED | {"find"=>"fs.files", "filter"=> {:"metadata.place"=>BSON::ObjectId('56d8f925e301d0390200000c')}}
=> 1
Executing the View::Aggregation only executes the aggregation pipeline. It does not execute find. Since our pipeline asks for all documents, we get size (6) instead of one (1).
A: You can test for object type with is_a? and case. See the hint provided about testing the incoming parameter for type.
case
when object.is_a?(Place)
@place=BSON::ObjectId.from_string(object.id)
Also, note from the hint that you can simply convert whatever String or ObjectId form you have, to what you need, with the following functions
- object.to_s
- BSON::ObjectId.from_string("...")
Your method is required to use or convert what it was passed, to what it needs. Keep an eye on the physical form of the documents in the database and the terms in the query debug to make sure you have done this correctly.
I have the addresscomponent.rb file under models folder. But I still receive error uninitialized constant AddressComponent
class AddressComponent
...
end
A: Rails uses snake_case.rb class file naming convention. All lower-case with separation with underscores.
That means that every capital letter in your ClassName
should be denoted with an underscore in the file name (e.g., class_name.rb
).
You are missing an underscore in your filename. So the class AddressComponent
needs to be in address_component.rb
.
Should this be 2 classes implemented on the model file place.rb where the "Place" class is also implemented ?
A: Yes, the custom types should be separate classes placed in the model directory as done in the module#3, formative practice exercise.
$ tree app/models/
app/models/
|-- address.rb <<===
|-- bike_result.rb
|-- concerns
|-- entrant.rb
|-- event.rb
|-- leg_result.rb
|-- placing.rb <<===
|-- point.rb <<===
|-- race.rb
|-- race_ref.rb
|-- racer_info.rb
|-- racer.rb
|-- run_result.rb
`-- swim_result.rb
It is important that they by plain Ruby classes saved in snake_case.rb files and, of course, have the required methods.