you can also see some examples here: http://technicaldebt.com/?cat=30
jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA
brandonweiss said the following on 4/23/11 1:20 PM:
class Substance
include MongoMapper::Document
many :datapoints, :order => "name", :extend => DatapointsExtensions
end
Here, I've put my extensions in a module:
module DatapointsExtensions
def energy
find_all{ |d| d.name =~ /^energy_/ }
end
def env
find_all{ |d| d.name =~ /^env_/ }
end
def hum
find_all{ |d| d.name =~ /^hum_/ }
end
.....
end
You declare them right on the many declaration:
many :datapoints, :order => "name", do
def energy
find_all{ |d| d.name =~ /^energy_/ }
end
def env
find_all{ |d| d.name =~ /^env_/ }
end
def hum
find_all{ |d| d.name =~ /^hum_/ }
end
.....
end
You'll have to dig in to the source/docs to find all the available methods.
Jamie
> --
> You received this message because you are subscribed to the Google
> Groups "MongoMapper" group.
> For more options, visit this group at
> http://groups.google.com/group/mongomapper?hl=en?hl=en
>> Patient.where(:last_name=>/john/i).class
=> Plucky::Query
>> Patient.where(:last_name=>/john/i).all.class
=> Array
>> Patient.where(:last_name=>/john/i).all.count
=> 1
>> Patient.where(:last_name=>/john/i).first.class
=> Patient
>> Patient.sort(:created_at.desc).first.class
=> Patient
Since you didn't present any model code, I am going to assume "releases"
is a scope.
class Encounter
include MongoMapper::Document
...
# Associations :::::::::::::::::::::::::::::::::::::::::::::::::::::
many :events, :limit => 30, :order => 'msg_timestamp desc' do
...
def images
where(:type =>
[EventConstants::EventType.to_text(EventConstants::EventType::IMAGE)]).order(:created_at.desc).all
end
def charts
where(:type =>
[EventConstants::EventType.to_text(EventConstants::EventType::ED_SUMMARY)],
:file_version.in => ["P", "F"]).order(:created_at.desc).all
end
def admits
all(:type =>
[EventConstants::EventType.to_text(EventConstants::EventType::ADMIT)])
end
end
...
end
# For a given encounter
enc=Encounter.find('4dadad188951a20727000160')
>> enc.events.images.count
=> 7
>> enc.events.images.class
=> Array
>> enc.events.images.first
=> #<Event created_at: Tue, 19 Apr 2011 15:41:15 UTC +00:00,
file_version: nil, title: "Image", updated_at: Tue, 19 Apr 2011 15:41:15
UTC +00:00, file_location: "4DBrainPerfusion-6.jpg", msg_timestamp: Tue,
12 Apr 2011 19:17:00 UTC +00:00, _id:
BSON::ObjectId('4dadad1b8951a2072700016f'), type: "Image", encounter_id:
BSON::ObjectId('4dadad188951a20727000160')>
jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA
brandonweiss said the following on 4/24/11 12:23 PM:
Product.first # Class. This would be an instance of Product
Product.first.releases # Array. This would be a return value of an
array, assuming Product <>----> * Release
Product.first.releases.where(something) # Array. This doesn't change the
above... merely adds a restrictive query clause
I am not sure why, but for me it seems more logical to start my clauses
with the where, and narrow them down further, or modify them... It is
much more "loose" than say a SQL SELECT query that requires things in
proper order... I would tend to write my queries in more or less this
fashion:
ModelClass.where(some criteria).[sort | order | another where clause |
fields | limit].[all | first | paginate]
I can picture one of those "man page" or SQL style of fancy ways to show
you how you can construct a mongomapper query given all the combinations
of options for each "position" in the query...
My advice is to make the query look as "natural" as possible in terms of
how you might read it aloud.
Product.releases.where(:major.gt => 1).sort(:minor.desc).first # Get the
latest 1.x release
(And, if the releases where clause query is common, you can create a
named scope.)
jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA
brandonweiss said the following on 4/23/11 1:20 PM:
I think this can be further refined and better sent to the various classes... But any times I will use a test to figure out what I will need in my code. But now it is late :=\it "should allow querying by age" dolist = Product.all(:conditions => {"releases.released_at" => {"$lt" => 5.days.ago}})list. size.should == 2list = Product.all(:conditions => {"releases.released_at" => {"$lt" => 25.days.ago}})list.count.should == 0end
To query for the products who have a release later than a certain date, you can do this:
Product.where( :"releases.released_at".gt => Time.now )
To get the actual release date you need, you do use Ruby's enumerable:
my_product.releases.select { |release| release.released_at > ... }
Wrapping it all together, if you want all releases after a certain date:
Product.where( :"releases.released_at".gt => Time.now ).map(&:releases).flatten.select { |release| release.released_at > Date.today }
So that's a bit convoluted, but that's why the recommendation is to "only embedded when the embedded documents will *always* be shown in the context of their parent". And, ah, the Time.now vs. Date.today thing is a side effect of MongoMapper providing a "Date" type while Mongo only has time...Date may be deprecated consequently, see: https://github.com/jnunemaker/mongomapper/issues/249
Peace,
Brian
And to underscore Brian's point... If you need to do heavy duty querying
and manipulation on a child association, consider NOT making it embedded.
jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA
Brian Hempel said the following on 4/25/11 8:53 AM:
in "words" what are you trying to query with your non-functioning query?
Product.first.releases.where(:released_at.gt => Time.now)
Are you trying to find the releases newer than some time for the first
product document in the database?
jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA
brandonweiss said the following on 4/24/11 11:41 PM:
Product where("releases.released_at" => {"$gt" => Time.now})
Definitely a slap the forehead moment.