[Nitro] [PATCH] Allow multiple joins_many style relationships between two classes (and relevent test case)

Rob Pitt rob at motionpath.com
Mon Feb 20 07:01:20 EST 2006


Export of our whiteboard discussion, request for comments (am
implementing this unless a better idea surfaces).


On Mon, 2006-02-20 at 11:39 +0000, Rob Pitt wrote:
> Problem is I only tested it with one half of the join, i.e because the
> property name is used in the join table construction the other side of
> the join makes a different join table (based on it's property name).
> 
> Attached is patch to join test-case to illustrate problem, (although
> tc_store already did, it's a join test so belongs in there).
> 
> I am a little stumped over what to do. I figure that if you have only
> one join relationship, it should be assumed to work in the old manner,
> if you make multiples then you should need to add hints
> like :foreign_name => :foobar ala has_many?
> 
> I really need this functionality so I'm giving it some thought. If
> anyone has ideas please post (or code) them! :)
> 
> Test case patch requires earlier patches (unfortunately since the
> concept is incomplete...)
> 
> 
> 
> On Fri, 2006-02-17 at 12:48 -0800, Bryan Soto wrote:
> > Just a quick note. After this is applied, there is a new test failure:
> > 
> >   1) Failure:
> > test_og(TCOgStore)
> >     [./test/og/tc_store.rb:263:in `features_test'
> >      ./test/og/tc_store.rb:76:in `test_og']:
> > <1> expected but was
> > <0>.
> > 
> > I'll try and check it out later.
> > 
> > On 2/17/06, Rob Pitt <rob at motionpath.com> wrote:
> >         WARNING: This patch causes join tables to be created with
> >         different
> >         names and will require you to manually copy join table data
> >         into newly
> >         named tables if applied to a project you are already using.
> >         
> >         Why would I make a patch that requires this? Not having this
> >         requirement 
> >         (i.e. doing it in an automated fashion) would be fairly
> >         complicated and
> >         a big drain on CPU.
> >         
> >         This patch still needs to be implemented at some point because
> >         it
> >         enables a desirable behaviour, and we are at 0.2 so we should
> >         make
> >         changes with big impacts like this now rather than later.
> >         
> >         This is a very minor modification so that a model like this
> >         behaves as
> >         it should:
> >         
> >         Class Article
> >           property :title, String 
> >         
> >           joins_many :first_join, Category
> >           joins_many :second_join, Category
> >           joins_many Category
> >         
> >           def initialize(title)
> >             @title = title
> >           end
> >         end
> >         
> >         Without this patch, items you push into .first_join are
> >         visible 
> >         in .second_join and the .categories join (all other
> >         combinations of this
> >         are also true).
> >         
> >         This is wrong, and this patch corrects this.
> >         
> >         
> >         _______________________________________________
> >         Nitro-general mailing list 
> >         Nitro-general at rubyforge.org
> >         http://rubyforge.org/mailman/listinfo/nitro-general
> >         
> >         
> > 
> > _______________________________________________
> > Nitro-general mailing list
> > Nitro-general at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/nitro-general
-------------- next part --------------
Solving the multiple join problem
=================================

Problem
=======

You should be able to join two models together multiple times, i.e.

class Article
  property :title, String
  joins_many :first_join, Category, :through => ArticleToCategory
  joins_many :second_join, Category, :through => ArticleToCategory
  joins_many :third_join, Category
  joins_many :fourth_join, Category
  joins_many Category
end

class Category
  property :title, String
  joins_many Article

  def initialize(title)
    @title = title
  end
end

At present .third_join, .fourth_join and .categories all return the
same result.

First Solution
==============

Add the property name to the join table construction, i.e.:

  * ogj_article_category

becomes:

  * ogj_article_category_third_join
  * ogj_article_category_fourth_join
  * ogj_article_category_categories

The problem with this soultion was category.articles then no longer
returns the same as article.categories as it refers to a seperate join
table:

  * ogj_article_category_articles

Proposed solution:
==================

No effective way of automatically determining the relationships could
be determined. Hints must be provided by providing the join table name
for extra joins:

class Article
  property :title, String
  joins_many :first_join, Category, :through => ArticleToCategory
  joins_many :second_join, Category, :through => ArticleToCategory
  joins_many :third_join, Category, :table => :ogj_article_category_third
  joins_many :fourth_join, Category, :table => :ogj_article_category_fourth
  joins_many Category
end

class Category
  property :title, String
  joins_many Article
  joins_many :third_join, Article, :table => :ogj_article_category_third
  joins_many :fourth_join, Article, :table => :ogj_article_category_fourth

  def initialize(title)
    @title = title
  end
end


More information about the Nitro-general mailing list