Topic: help with one-to-one relationship

Hi, please could someone help me with this basic problem:

I have 2 tables, weddings, and continents. Continents is a lookup table that contains 7 continents.

I basically want to return a list of all weddings in a particular continent, by continent name.

@wedding = Wedding.continents.find(:all, :conditions => "continent = 'Africa'")

But i get the error:
undefined method `continents' for Wedding:Class

Why is this?

I have:

class Wedding < ActiveRecord::Base
  belongs_to :continent

and

class Continent < ActiveRecord::Base
  has_one :wedding

many thanks

Re: help with one-to-one relationship

Try

Continent.find_all_by_name("Africa");

This assumes that store your continent names in a column called name

I am a little bit confused because you define Continent has having only one wedding, but you want to return all of the weddings on a particular continent, implying that there is more than one.

Re: help with one-to-one relationship

Thanks dahuk, your quite right, Continent can have many weddings.

I am not sure your solution works for me though, as i need to get a handel on all weddings from a continent, not just a handel on the continent itself.

Why cant i use:

@wedding = wedding.continents....

Re: help with one-to-one relationship

I think i can ask my question more concisely now...

If i have a one to many relationship between continents and weddings, how do i use active record to retrieve all wedding records where a condition is satisfied in an associated continent?

Re: help with one-to-one relationship

Try:

@weddings = @continent.weddings.find(:all, :conditions => 'foo = 'bar')

Of course you'll need to insert your own conditions.

Railscasts - Free Ruby on Rails Screencasts

Re: help with one-to-one relationship

Thanks for the help ryanb, really appreciated, unfortunately when i try that, i get the error:

You have a nil object when you didn't expect it!

Re: help with one-to-one relationship

 
africa = Continent.find_by_name("africa")
@weddings = Wedding.find_all_by_continent_id(africa.id)

I think this will work for you.

Re: help with one-to-one relationship

pingu wrote:

Thanks for the help ryanb, really appreciated, unfortunately when i try that, i get the error:

You have a nil object when you didn't expect it!

Did you set the @continent instance variable? You need to have a continent before you can retrieve the weddings that go with it.

Railscasts - Free Ruby on Rails Screencasts

Re: help with one-to-one relationship

you are getting the nil object error because you have not created @continent.

It will work if you set @continent to the continent with the name of Africa

Re: help with one-to-one relationship

dahuk wrote:

 
africa = Continent.find_by_name("africa")
@weddings = Wedding.find_all_by_continent_id(africa.id)

I think this will work for you.

Or you could do this:

@weddings = africa.weddings

Or this:

@weddings = Wedding.find(:all, :include => :continent, :conditions => "continents.name='africa'")

Railscasts - Free Ruby on Rails Screencasts

Re: help with one-to-one relationship

Thanks for the replies, but i still cant get it working, its driving me mad. I tried...

    @continent = Continent.find(:all)
    @weddings = @continent.weddings.find(:all, :conditions => "foo = 'bar'")

but got the error

undefined method `weddings' for #<Array:0x24fb1c4>

Have my models been screwed up in someway?

Re: help with one-to-one relationship

ryanb, i have got it to at least run by altering your code slightly:

@weddings = @continent[0].weddings.find(:all, :conditions => 'foo = 'bar')

the addition of the [0] gets past the error message i was getting, problem is, i dont really want to specify [0].

please, any ideas? i have worked solidly on this problem for a day and half now.

Re: help with one-to-one relationship

Are you still using

@continent = Continent.find(:all)

Because that will return an array.  How are you setting continent?

Re: help with one-to-one relationship

Yes, i am using:

@continent = Continent.find(:all)

Re: help with one-to-one relationship

If you don't want to specify [0], you will have to get a single continent in @continent.

Try

@continent = Continent.find(:first)

This will return the first continent. You could also set conditions like

name_of_continent_you_want = "Africa"
@continent = Continent.find(:first, :conditions => ['name = ?', name_of_continent_you_want])

This will give you the continent that has the name Africa

Also, if you write code=ruby in the brackets instead of just code, it will highlight your code for you.

Last edited by dahuk (2006-11-17 12:34:07)

Re: help with one-to-one relationship

sorted! thankyou all ever so much.