Forum: Ruby on Rails belongs_to relation busted....why?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
meltman (Guest)
on 2006-03-24 04:08
Ok, been banging my head on this and just can't figure it. Normally, any
table that has a belongs_to to another table you can easily access it
by:

table1.table2.field

And it works perfectly for one table I have. Let's call it... tags. So,
I've got:

Tag -> has_many :blah_tags
Blah -> has_many :blah_tags
Blah_tag -> belongs_to :tag, belongs_to :blah

Ok, works fine. Based on a blah_tag entry, I can go blah_tag.blah.name
(or whatever). No problem.

Substitute, an identical setup for say Colour, and bam. The whole thing
throws nils everywhere. I may have a big batch of valid colour_tags, but
try to go: colour_tag.colour => NIL!

I don't get it. Identical table setups....identical code.... is colour
reserved? Do I need to restart servers or something (tried that...)? Am
I going crazy?

It makes no sense to me.

Thanks!
mm
Norman T. (Guest)
on 2006-03-24 13:20
(Received via mailing list)
Am Freitag, den 24.03.2006, 03:08 +0100 schrieb meltman:
> Blah -> has_many :blah_tags
> reserved? Do I need to restart servers or something (tried that...)? Am
> I going crazy?
>
> It makes no sense to me.

Please show us some concrete code.

--
Norman T.

http://blog.inlet-media.de
meltman (Guest)
on 2006-03-24 15:16
Well I don't have it in front of me at the moment, but there's nothing
crazy going on:

class Colour < ActiveRecord::Base
has_many :entry_colours
end

class Entry < ActiveRecord::Base
has_many :entry_colours
end

class EntryColour < ActiveRecord::Base
belongs_to :colour
belongs_to :entry
end

class Search < ApplicationController
def search
   @colour = Colour.find(:first, :conditions => [ "name=Red" ])
   @results =  EntryColour.find(:all,:conditions
=>["colour_id=?",@colour.id])

   #this bit is actually embedded in HTML but we'll put it here...
   @results.each |result| do
      result.entry.name
   end
end
end

I don't know if there's just something out of whack.... or what. I tried
flushing the temp files, restarting everything... no dice. But another
table with literally the identical setup works fine. Does it hate the
word colour?

The things in @results are valid.

mm

Norman T. wrote:
> Am Freitag, den 24.03.2006, 03:08 +0100 schrieb meltman:
>> Blah -> has_many :blah_tags
>> reserved? Do I need to restart servers or something (tried that...)? Am
>> I going crazy?
>>
>> It makes no sense to me.
>
> Please show us some concrete code.
>
> --
> Norman T.
>
> http://blog.inlet-media.de
Alan F. (Guest)
on 2006-03-24 15:57
meltman wrote:
> Well I don't have it in front of me at the moment, but there's nothing
> crazy going on:
>
> class Colour < ActiveRecord::Base
> has_many :entry_colours
> end
>
> class Entry < ActiveRecord::Base
> has_many :entry_colours
> end
>
> class EntryColour < ActiveRecord::Base
> belongs_to :colour
> belongs_to :entry
> end

You seem to be querying a slightly odd way.   If Colour has_many
EntryColours, you should be able to say @colour.entry_colours.each{ |ec|
...}  Can you ?

Another thing to try is use script/console to load a Colour and inspect
it.

Silly Question, perhaps, but is there a reason you're specifically
avoiding  has_and_belongs_to_many ?

Then you could do
  @colour = Colour.find(:first, :conditions => [ "name=Red" ])
  @colour.entries.each{|entry| entry.name}
or
  @entry.colours.each{|colour| colour.name}

Can you post the schema for those three tables ?  It may be down to
foreign key placement and/or whether the join table has it's own id?


A.
meltman (Guest)
on 2006-03-24 16:19
Alan F. wrote:
> You seem to be querying a slightly odd way.   If Colour has_many
> EntryColours, you should be able to say @colour.entry_colours.each{ |ec|
> ...}  Can you ?

Indeed I probably can (code not in front of me right now), or at least I
should be. I'm relatively new to this whole Rails thing, and that
certainly would be a much easier way to do the query.

> Silly Question, perhaps, but is there a reason you're specifically
> avoiding  has_and_belongs_to_many ?

Hahaha, no, and I probably should be using it since the queries are
certainly easier. Like I said, pretty new to the whole Rails thing, and
really, to relational DBs in general. (I'm a recent perl convert whose
been living in flat-file hell for too long!) So I appreciate the
patience for my obviously moronic inquiries.

Ok, so the schema (also not in front of me is pretty basic):

table: colours
id (int, auto-inc, primary key)
name (varchar)

table: entries
id (int, auto-inc, primary key)
name (varchar)

table: entry_colours
colour_id (int, primary key)
entry_id (int, primary key)

That's it... it's really just something I'm fooling around with to get
my bearings in the new environment. What has me really mystified is that
I had it working with another 'join' table or whatever, and then when I
tried adding this second one, it didn't work. So I'm a bit mystified.

Thanks again.
mm
Alan F. (Guest)
on 2006-03-24 16:48
meltman wrote:
> Alan F. wrote:
>> You seem to be querying a slightly odd way.   If Colour has_many
>> EntryColours, you should be able to say @colour.entry_colours.each{ |ec|
>> ...}  Can you ?
>
> Indeed I probably can (code not in front of me right now), or at least I
> should be. I'm relatively new to this whole Rails thing, and that
> certainly would be a much easier way to do the query.
>
>> Silly Question, perhaps, but is there a reason you're specifically
>> avoiding  has_and_belongs_to_many ?
>
> Hahaha, no, and I probably should be using it since the queries are
> certainly easier. Like I said, pretty new to the whole Rails thing, and

Aha! :-)  Then life's about to get easier.

So, here goes...

table: colours (id, name)
table: entries (id, name)
table: colours_entries (colour_id, entry_id)

note its important the the two names in the join table be in alpha order
for rails automagic to work...entries_colours won't work.

model: Colour, has_and_belongs_to_many :entries
model: Entry, has_and_belongs_to_many :colours

You can now do:

red = Colour.find(1)
red.entries.each{ |entry| entry.do_something }

or
entry = Entry.find(1}
entry.colours.each{ |colour| colour.do_something }

You can go from entry to color back to entry again..

entry.colours.each{ |colour| colour.entries.name }

For more info, see
http://www.slash7.com/cheats/activerecord_cheatsheet.pdf

Alan
meltman (Guest)
on 2006-03-24 16:54
Alan F. wrote:
> Aha! :-)  Then life's about to get easier.

Indeed it has!

> note its important the the two names in the join table be in alpha order
> for rails automagic to work...entries_colours won't work.

Oh my god! Alpha order! Man, is that documented somewhere?!

> model: Colour, has_and_belongs_to_many :entries
> model: Entry, has_and_belongs_to_many :colours

Oh man, so much easier, so you don't even *need* the intermediate model
anymore....

I swear, every day Rails gets better and better.

Thanks so much for the help!

mm
Alan F. (Guest)
on 2006-03-24 17:35
meltman wrote:
> Alan F. wrote:
>> Aha! :-)  Then life's about to get easier.
>
> Indeed it has!
>
>> note its important the the two names in the join table be in alpha order
>> for rails automagic to work...entries_colours won't work.
>
> Oh my god! Alpha order! Man, is that documented somewhere?!
>

Indeed it is!
http://rails.rubyonrails.com/classes/ActiveRecord/...
This topic is locked and can not be replied to.