mongo mapper model reflection

80 views
Skip to first unread message

Nick Kaltner

unread,
May 17, 2011, 7:13:26 PM5/17/11
to MongoMapper
Hi,
I'm trying to work out a way to get the key names defined in a model.
I want to generate a json schema document from the model/validations
on the model.

I have some code that does u.class.column_names or u.keys but if I add
a key to the model, then remove it, it stays in this list forever. Is
there any way to just see the currently defined keys? If not, what
would be the best way for me to add this functionality?

Cheers,
Nick

Dhruva Sagar

unread,
May 18, 2011, 6:44:13 AM5/18/11
to mongo...@googlegroups.com
On Wed, May 18, 2011 at 04:43, Nick Kaltner <anko.com@gmail.com> wrote:
Hi,
I'm trying to work out a way to get the key names defined in a model.
I want to generate a json schema document from the model/validations
on the model.

I have some code that does u.class.column_names or u.keys but if I add
a key to the model, then remove it, it stays in this list forever.  Is
I don't understand this point, the keys collection surely will change if you add / remove keys from the model.
Model.keys.keys will always reflect the keys defined within the model.
there any way to just see the currently defined keys? If not, what
would be the best way for me to add this functionality?

Cheers,
Nick

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



--
Thanks & Regards,
Dhruva Sagar
----------------------------
Technical Developer - Mentor,

Become an expert in Rails. Join our 3 day Rails workshop and learn Ruby, Rails 3, Cucumber and Git.

Jon Kern

unread,
May 18, 2011, 8:30:06 AM5/18/11
to mongo...@googlegroups.com
so are you trying to display the schema for a schema-less database <g>?

trying to make an ERD? A Mongo Viewer?

Anyway, look what happens when you run this simple test: https://gist.github.com/978476

Seems MongoMapper will always show you all keys ever made... the superset, as it were. This makes perfect sense if you understand that MongoMapper Don't Care!

I know I have already done things to get rid of no-longer needed/used/correct keys. Maybe this will help:

  def self.purge_msid_key
    uppercase_msid_acts = Account.where(:MSID.exists => true).count
    if uppercase_msid_acts > 0
      @cactus_log ||= []
      Account.unset({}, :MSID)
      end_count = Account.where(:MSID.exists => true).count
      @cactus_log << "Cleaned up #{uppercase_msid_acts - end_count} Accounts with errant MSID key."
    end
  end


jon
blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA

Nick Kaltner said the following on 5/17/11 7:13 PM:

Brian Hempel

unread,
May 18, 2011, 9:21:40 AM5/18/11
to mongo...@googlegroups.com
This is probably a consequence of issue #195 https://github.com/jnunemaker/mongomapper/issues/195 .  Right now, any key that's ever defined on an instance ever ends up being defined for all objects of that class.  In practice, it means that some of your models might get saved with extra keys :)

Brian

Jon Kern

unread,
May 18, 2011, 9:34:47 AM5/18/11
to mongo...@googlegroups.com
I can see it both ways... I also posted about this: http://technicaldebt.com/?p=952

If the key was a mistake, remove it.

If the key was added for an instance or three... but it is not in the class, should it be revealed or hidden?

I can see MongoDB opting for the default to show the superset. It would be maddening to know you added some documents with certain keys, only to not ever be able to find them! Also, this allows you to be much more dynamic about storing new key/value pairs on the fly and being able to always know what keys are available. (More akin to RDF "loose" data schemas.)

So, I don't think it is an either / or thing.
Brian Hempel said the following on 5/18/11 9:21 AM:

Jamie Orchard-Hays

unread,
May 18, 2011, 10:34:58 AM5/18/11
to mongo...@googlegroups.com
ModelName.keys.keys gives you a list of keys defined in the model.

However, if you have any key in a document in the collection NOT defined in the model, it will also be returned in ModelName.keys.keys. You might say that MongoMapper is self-aware. ;-)

if you have keys in your collection of docs you no longer want, $unset is your friend.

Jamie

Brandon Keepers

unread,
May 18, 2011, 11:44:38 AM5/18/11
to mongo...@googlegroups.com
The goal is to have dynamic keys tracked at the instance level instead of class, but we need to rework the attributes a little first.


=b

Nick Kaltner

unread,
May 18, 2011, 6:58:08 PM5/18/11
to MongoMapper


On May 18, 10:30 pm, Jon Kern <jonker...@gmail.com> wrote:
> so are you trying to display the schema for a schema-less database <g>?
> trying to make an ERD? A Mongo Viewer?

I want to create a view of my data, based on the schema i've got in my
model. That way I could auto-matically generate forms (kinda the way
formtastic can do it). It just seems crazy that in a community where
we like to talk about DRY concepts, we are defining the constraints on
our data twice - in our model and in our views.

But yeah, I guess a Mongo Viewer is kinda an outcome of the project :)

Cheers,
Nick


> Anyway, look what happens when you run this simple test:https://gist.github.com/978476
> Seems MongoMapper will always show you all keys ever made... the superset, as it were. This makes perfect sense if you understand thatMongoMapper Don't Care!

Nick Kaltner

unread,
May 18, 2011, 7:25:22 PM5/18/11
to MongoMapper
Thanks everyone for your insight.

I guess a way my plugin could possibly work is by extending the key
method (maybe by monkey patch?) and store each key in a class
variable? Does that sound reasonable?

I am also planning on extending the definition of models so this would
work;

class User
include MongoMapper::Document
# allows you to define schema views per
role
plugin SchemaRole

key :name, String
key :age, Integer, :default => 0
key :description, String, :default => "I'm cool"
key :sex, String, :in => ["Male", "Female"]
key :dob, Date
key :title, String

schema :role => :user do
use :name
use :description
end
end

I guess in the short term, if I have a schema block with all my keys
listed I would be short circuiting the limitation of mongomapper
listing too many keys. But it's not very DRY and I still haven't
quite worked out how to store this schema data within a class variable
through a mongo_mapper plugin. Well maybe I have..

ruby-1.9.2-p180 :002 > u.class.instance_variable_get(:@current_schema)
=> {:admin=>[:name, :description]}

The point of all this jiggery-pokery is I want to automatically
generate schema's from my models that would include the validations
and allow the javascript on the front end to do client side
validations based on their authenticated role. Whether or not that's
a good idea will be something I find out through further
experimentation but I really don't like the current situation of
defining my validations several times.. Also json schema allows for
nice consumable services with a firm definition without the overhead
of SOAP.

:)

Nick

Jon Kern

unread,
May 18, 2011, 8:21:33 PM5/18/11
to mongo...@googlegroups.com
I still don't understand why you do not want some keys in your views...

Are these extra keys bogus (a mistake)? If so, whack them as I illustrated below with unset

Otherwise, if they are legit, why wouldn't you want them in your form display?

I have been thinking of a future application where I can be much less concerned about official models and allow users to define extra attributes on the fly (for simple info) and have forms happily add the new keys, and mongo happily store the new data...

I can see a model maintenance page where at most you suppress certain keys from the view if you get tired of looking at them :-)
Nick Kaltner said the following on 5/18/11 6:58 PM:

Nick Kaltner

unread,
May 18, 2011, 11:47:17 PM5/18/11
to MongoMapper
I don't want my model to be representative of the database, but to be
representative of the keys I want exposed to my application.

No the keys aren't necessarily bogus, I just don't want the
application to know about them anymore - maybe I have data there that
I don't want the application to touch.

Strictly speaking, there is no reason why I can't just deal with the
fact that old keys are still exposed. It just doesn't seem right to
me, and the overhead of always dealing with extra keys forever or a
manual process to clean them seems a bit wasteful. I've edited the
key out of my model, I don't want to care about it again (as far as
the application is concerned).

I hope I am making some sense..

Cheers,
Nick


On May 19, 10:21 am, Jon Kern <jonker...@gmail.com> wrote:
> I still don't understand why you do not want some keys in your views...
> Are these extra keys bogus (a mistake)? If so, whack them as I illustrated below with unset
> Otherwise, if they are legit, whywouldn'tyou want them in your form display?
> I have been thinking of a future application where I can be much less concerned about official models and allow users to define extra attributes on the fly (for simple info) and have forms happily add the new keys, and mongo happily store the new data...
> I can see a model maintenance page where at most you suppress certain keys from the view if you get tired of looking at them :-)jon blog:http://technicaldebt.comtwitter:http://twitter.com/JonKernPA

Jon Kern

unread,
May 19, 2011, 8:54:04 AM5/19/11
to mongo...@googlegroups.com
yeah, i understand... but to expect the database to be flexible in
knowing what you can query for or allow inserting anything, and yet to
also want a strict schema seems like a bit too much to expect. Isn't
this a bit of incongruent behavior?

I like your hidden key example (and I assume not just the ID).

Sounds like you need a "go-between" layer/filter that expresses what you
want the user to see. Since the "filter" is the smaller of the two...
Maybe you simply need to maintain a list of "keys to ignore" in each
model? So the keys you show are a simple netting out of the available
minus the keys_to_hide...


Nick Kaltner said the following on 5/18/11 11:47 PM:

Billy

unread,
May 19, 2011, 11:57:05 PM5/19/11
to mongo...@googlegroups.com
Yeah, its annoying -- but can be circumvented by ensuring you call .fields() on your queries to only request what you need. You should be doing that anyway :) This coubled with 'attr_accessible' will let you control what things go in, and what comes back out. The field will still be in the model but the only harm it will do is take up a trivial amount of space for each document.


Reply all
Reply to author
Forward
0 new messages