Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Some associations still unsupported?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  6 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
juliangruber  
View profile  
 More options Feb 4 2012, 5:25 pm
From: juliangruber <misterio...@googlemail.com>
Date: Sat, 4 Feb 2012 14:25:30 -0800 (PST)
Local: Sat, Feb 4 2012 5:25 pm
Subject: Some associations still unsupported?
Hey,

I'm still new to mongo_wrapper so I hope my question isn't due to my
lack of knowledge.

I want to link two models in a way that I haven't seen examples of yet
with mongo_wrapper:

Model ContentType: name[String].
Model Relation: Each Relation has 2 ContentTypes referenced. rel.from
= [ContentType] rel.to = [ContentType]. Embedding is not an option
since each ContentType can belong to multiple relations.

So basically I have a [ContentType] N:N [Relation], [Relation] N:2
[ContentType] association model.

How can this be done? I tried in the Relation model:
one :content_type, :in => :from
one :from, :class_name => 'ContentType'
and other variations with :typecast eg.

Simply storing the respective _id's as ObjectId is no problem, but
then rel.from is just an id and I have to do the lookups myself via
ContentType.find(rel.from).

The only way I got this working is in the console with
c1 = ContentType.create
c2 = ContentType.create
c1.save!
c2.save!
rel = Relation.create
rel.from = c1
rel.to = c2
rel.save!
rel = Relationship.all.first => right ContentType

But then, rel doesn't save the _ids of the ContentTypes, rather the
_id of the Relation is saved in the content_types' relationship_id
field, which I don't find optimal and adds complexity to simple crud
operations.

Help is greatly appreciated, I hope my problem is clear.

-- Julian Gruber.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
John Nunemaker  
View profile  
 More options Feb 4 2012, 6:03 pm
From: John Nunemaker <nunema...@gmail.com>
Date: Sat, 4 Feb 2012 18:03:22 -0500
Local: Sat, Feb 4 2012 6:03 pm
Subject: Re: [MongoMapper] Some associations still unsupported?

So the end goal is relating two content types to each other?

On Sat, Feb 4, 2012 at 5:25 PM, juliangruber <misterio...@googlemail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juliangruber  
View profile  
 More options Feb 5 2012, 11:41 am
From: juliangruber <misterio...@googlemail.com>
Date: Sun, 5 Feb 2012 08:41:29 -0800 (PST)
Local: Sun, Feb 5 2012 11:41 am
Subject: Re: Some associations still unsupported?
Yes, but the relation I aim for is not in the docs.

One-to-Many doesn't work because I need 2 belongs_to statements in my
Relationship-Model
Many-to-Many doesn't work because I again have two keys, :from
and :to, that need to reference back.

For clarity, my models atm look like:

-------
class ContentType
  include MongoMapper::Document
  key :name, String
  many :relationships
end
-------
class Relationship
  include MongoMapper::Document

  key :type, Integer

  #one :from, :class_name => 'ContentType', :foreign_key
=> :relationship_ids
  #one :to, :class_name => 'ContentType', :foreign_key
=> :relationship_ids
  belongs_to :from, :class_name => 'ContentType', :typecast =>
'ObjectId'
  belongs_to :to, :class_name => 'ContentType', :typecast =>
'ObjectId'
end
-------

And I want to do:
r = Relationship.create
cfrom = ContentType.create
cto = ContentType.create
r.from = cfrom
r.to = cto
cfrom.relationships

or is this not the right data model with this db and the mongomapper
philosophy?
I could of cause just write custom modelfunctions to update the keys
in the inverse models.

I could save the Relationships embedded in both ContentTypes (I always
want to link 2 ContentTypes) but this also creates management
overhead.

Julian

On Feb 5, 12:03 am, John Nunemaker <nunema...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
John Nunemaker  
View profile  
 More options Feb 6 2012, 9:32 am
From: John Nunemaker <nunema...@gmail.com>
Date: Mon, 6 Feb 2012 09:32:30 -0500
Local: Mon, Feb 6 2012 9:32 am
Subject: Re: [MongoMapper] Re: Some associations still unsupported?

You want cfrom.relationships to check both the from and the to?

On Sun, Feb 5, 2012 at 11:41 AM, juliangruber <misterio...@googlemail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juliangruber  
View profile  
 More options Feb 6 2012, 10:33 am
From: juliangruber <misterio...@googlemail.com>
Date: Mon, 6 Feb 2012 07:33:08 -0800 (PST)
Local: Mon, Feb 6 2012 10:33 am
Subject: Re: Some associations still unsupported?
Ideally cfrom would have an array with all ids...or else yes, check
from and to.

However, I decided to go with embedded documents for relationships for
now, but still I think the original problem is worth solving isn't it?

On Feb 6, 3:32 pm, John Nunemaker <nunema...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Brian Hempel  
View profile  
 More options Feb 6 2012, 11:22 am
From: Brian Hempel <br...@ihswebdesign.com>
Date: Mon, 6 Feb 2012 11:22:06 -0500
Local: Mon, Feb 6 2012 11:22 am
Subject: Re: [MongoMapper] Re: Some associations still unsupported?
So you want to do join tables in MongoMapper, a la the :through option or has_and_belongs_to_many in ActiveRecord? http://guides.rubyonrails.org/association_basics.html#the-has_many-th...

I thought about this problem a bunch while working on MongoMapper's association documentation.

There's the supported Many-to-Many, which works find with objects of the same class:

class ContentType
  include MongoMapper::Document
  key :from_content_type_ids, Array, :typecast => 'ObjectId'
  many :from_content_types, :in => :from_content_type_ids

  # sorry, no many-to-many inverse yet, our bad!
  def to_content_types
    ContentType.where(:from_content_type_ids => self.id)
  end

  def related_content_types
    (from_content_types.to_a + to_content_types.to_a).uniq
  end
end

cfrom = ContentType.create
cto = ContentType.create
cto.from_content_types << cfrom
cto.related_content_types
cfrom.related_content_types

e.g. in Mongo...

{
  _id: ObjectId('abc123'),
  from_content_type_ids: [
    ObjectId('abc456'),
    ObjectId('abc789'),
  ]

}

{
  _id: ObjectId('abc456')

}

{
  _id: ObjectId('abc789')

}

You can also roll your own join table as two one-to-many relationships:

class Relationship
  include MongoMapper::Document
  key :from_content_type_id, ObjectId
  key :to_content_type_id,   ObjectId
  belongs_to :from_content_type, :class_name => 'ContentType'
  belongs_to :to_content_type,   :class_name => 'ContentType'
end

class ContentType
  include MongoMapper::Document
  many :from_relationships, :class_name => 'Relationship', :foreign_key => :from_content_type_id
  many :to_relationships,   :class_name => 'Relationship', :foreign_key => :to_content_type_id

  def relationships
    from_relationships.to_a + to_relationships.to_a
  end

  def from_content_types
    from_content_type_ids = from_relationships.map { |r| r.from_content_type_id }
    ContentType.where(:id.in => from_content_type_ids)
  end

  def to_content_types
    to_content_type_ids = to_relationships.map { |r| r. to_content_type_id }
    ContentType.where(:id.in => to_content_types)
  end

  def related_content_types
    (from_content_types.to_a + to_content_types.to_a).uniq
  end
end

r = Relationship.create
cfrom = ContentType.create
cto = ContentType.create
r.from_content_type = cfrom
r.to_content_type = cto
r.save
cfrom.relationships
cfrom.related_content_types

Or you can roll your relationship objects as embedded docs. You'd set it up like MongoMapper's standard Many-to-Many BUT instead of storing an array of id's you store an array of embedded documents.  It would look like this (note that embedded docs always have their own id):

{
  _id: ObjectId('abc123'),
  from_content_type_ids: [
    { _id: ObjectId('e321'), from_content_type_id: ObjectId('abc456') },
    { _id: ObjectId('e654'), from_content_type_id: ObjectId('abc789') }
  ]

}

{
  _id: ObjectId('abc456')

}

{
  _id: ObjectId('abc789')

}

(Email the list again if you want to go this route and need code help...)

The advantage of embedded docs over MongoMapper's standard Many-to-Many is that you can add attributes to your relationship embedded documents to store more information about the relation, just like you can with ActiveRecord's many :through. For example, you could add a "related_at" timestamp to know when content types were linked up. BUT, if you don't need extra information about the relationship, you don't gain anything with embedded docs over MongoMapper's Many-to-Many.

Development wise, MM needs a Many-to-Many inverse first, then perhaps eager loading, and then maybe we can talk about "join tables" in Mongo.  The embedded relationship documents approach is much more Mongo-y than a full out join collection.  Embedded relationship document are the same number of queries as the current Many-to-Many implementation.  A join collection requires an extra query because Mongo doesn't support joins.  With the development pain to code it and maintain it, it might not be worth the gain. Does anyone else need join tables?

Does that answer your question?

Brian

On Feb 6, 2012, at 10:33 AM, juliangruber wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »