Skip to content
Faacy Farook edited this page Mar 22, 2016 · 4 revisions

Frequently Asked Questions (FAQs) - Course 3 Module 2

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

Table of Contents

Q: How to correctly use find with aggregation framework

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).

Back To Top

Q: How could a method accept different types of optional parameters and apply them accordingly?

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.

Back To Top

Q: Why do I get thr error "uninitialized constant"?

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.

Back To Top

Q: On assignment places collection (3) and (4), I don't understand "Implement a custom type"?

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.

Back To Top