Forum: Ruby on Rails many to one relation

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.
P. P. (Guest)
on 2007-01-19 08:23
-i searched through the news group but couldn't find the answer for my
problem.
example:

----------- classes ----------
class Car < ActiveRecord::Base
  has_one :colour
  def after_create()
    colour = Colour.new
    colour.name = 'colour1'
    colour.save
  end
end

class Chair < ActiveRecord::Base
  has_one :colour
end

class Colour < ActiveRecord::Base
end
-------------- tables ---------
create table cars(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
varchar(50),colour_id int NOT NULL, primary key(id));

create table chairs(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
varchar(50),colour_id int NOT NULL);

create table colours(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
varchar(50));

- i consider it a many to one relation because diferent types of items
are refering to one type (Car and Chair both have colour).
- i wrote the models as above i create a Car object, i save it but
alwayes my colour_id in the database remains 0.
  I would appreciate if your could give me a hint.
Darren E. (Guest)
on 2007-01-19 09:15
Hi

I'm absolutely not an expert in this, but I would have expected:

class Colour < ActiveRecord::Base
  belongs_to :chair
  belongs_to :car
end

I think that with a has_one relation, you require a belongs_to on the
other side of the relation.

Darren


P. Pantouffe wrote:
> -i searched through the news group but couldn't find the answer for my
> problem.
> example:
>
> ----------- classes ----------
> class Car < ActiveRecord::Base
>   has_one :colour
>   def after_create()
>     colour = Colour.new
>     colour.name = 'colour1'
>     colour.save
>   end
> end
>
> class Chair < ActiveRecord::Base
>   has_one :colour
> end
>
> class Colour < ActiveRecord::Base
> end
> -------------- tables ---------
> create table cars(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
> varchar(50),colour_id int NOT NULL, primary key(id));
>
> create table chairs(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
> varchar(50),colour_id int NOT NULL);
>
> create table colours(id int PRIMARY KEY NOT NULL AUTO_INCREMENT,name
> varchar(50));
>
> - i consider it a many to one relation because diferent types of items
> are refering to one type (Car and Chair both have colour).
> - i wrote the models as above i create a Car object, i save it but
> alwayes my colour_id in the database remains 0.
>   I would appreciate if your could give me a hint.
Darren E. (Guest)
on 2007-01-19 09:19
Hi

In addition to this, isn't the relation you require in both cases a
has_many, i.e. both chairs and cars have many colours, and a colour
belongs to a chair or a car?

Darren
P. P. (Guest)
on 2007-01-19 09:46
Hi and tkns for the reply

i've tried with:

class Colour < ActiveRecord::Base
  belongs_to :chair
  belongs_to :car
end

and modified after_create
  def after_create()
    colour = Colour.new
    colour.name = 'colour1'
    colour.save
    save()             # <- this one
  end

my colour_id still remains 0.
- i'm beginner in both databases and ruby. I interpret a has_many
relation as a parent_id colour for the colours table and i don't think
this is correct.
  There's something wrong in what i'm doing but I don't know what. :D
Alan F. (Guest)
on 2007-01-19 11:57
P. Pantouffe wrote:
> Hi and tkns for the reply
>
> i've tried with:
>
> class Colour < ActiveRecord::Base
>   belongs_to :chair
>   belongs_to :car
> end
>
> and modified after_create
>   def after_create()
>     colour = Colour.new
>     colour.name = 'colour1'
>     colour.save
>     save()             # <- this one
>   end
>
> my colour_id still remains 0.
> - i'm beginner in both databases and ruby. I interpret a has_many
> relation as a parent_id colour for the colours table and i don't think
> this is correct.
>   There's something wrong in what i'm doing but I don't know what. :D


ALthough the english doesn't always read well, the belongs_to goes where
the foreign key is.

In your case, thats Car or CHair.  So

Car belongs_to Color, Color has_many Cars
Chair belongs_to COlor, Color has_many Chairs

As I said  you would say a "Car belongs to a colour" in english, but
thats how you say it in rails :)

A.
Alan F. (Guest)
on 2007-01-19 11:59
Alan F. wrote:

> ALthough the english doesn't always read well, the belongs_to goes where
> the foreign key is.
>
> In your case, thats Car or CHair.  So
>
> Car belongs_to Color, Color has_many Cars
> Chair belongs_to COlor, Color has_many Chairs
>
> As I said  you would say a "Car belongs to a colour" in english, but
> thats how you say it in rails :)
>
> A.

Sorry, that should have been "you *wouldn't* say...in english", and
there probably shouldn't be quite so many capital letters.

Alan
askegg (Guest)
on 2007-01-19 12:12
P. Pantouffe wrote:
> Hi and tkns for the reply
>
> i've tried with:
>
> class Colour < ActiveRecord::Base
>   belongs_to :chair
>   belongs_to :car
> end
>
> and modified after_create
>   def after_create()
>     colour = Colour.new
>     colour.name = 'colour1'
>     colour.save
>     save()             # <- this one
>   end
>
> my colour_id still remains 0.
> - i'm beginner in both databases and ruby. I interpret a has_many
> relation as a parent_id colour for the colours table and i don't think
> this is correct.
>   There's something wrong in what i'm doing but I don't know what. :D

I take it you mean the colour_id of your new Car remains unchanged?
This is what I would expect to happen given the code above, although it
will create an entry in the colour table.  What you haven't done is tie
the two records together.

RoR does a lot of nice things for you, like make associations appear as
if they are in the original model.  What does this mean?  When your
creating a new Car, try:

new_car = Car.new
new_car.colour = Colour.find_or_create_by_name "colour 1"
new_car.save

(I am no expert either, but I figure hanging out here and trying to
solve problems I will learn)
P. P. (Guest)
on 2007-01-19 13:39
Hi, thank u for anserwing me.
Indeed it works when i say car belongs to color (David must hove some
reason for switching it.) and putting the color creation code in a way
askegg wrote.
- it don't understand why my code in the after_create() method did not
work, the API says that ,,after_create() is called after Base.save on
new objects that haven’t been saved yet (no record exists)", in the
code:

 def after_create()
   colour = Colour.new
   colour.name = 'colour1'
   ...
 end

  colour is the Atribute, isn't it?
Alan F. (Guest)
on 2007-01-19 14:02
P. Pantouffe wrote:
> Hi, thank u for anserwing me.
> Indeed it works when i say car belongs to color (David must hove some
> reason for switching it.) and putting the color creation code in a way
> askegg wrote.
> - it don't understand why my code in the after_create() method did not
> work, the API says that ,,after_create() is called after Base.save on
> new objects that haven’t been saved yet (no record exists)", in the
> code:
>
>  def after_create()
>    colour = Colour.new
>    colour.name = 'colour1'
>    ...
>  end
>
>   colour is the Atribute, isn't it?

Then that would need to be @colour.  You just created a brand new
temporary variable.

A.
Alan F. (Guest)
on 2007-01-19 14:49
Alan F. wrote:

>>  def after_create()
>>    colour = Colour.new
>>    colour.name = 'colour1'
>>    ...
>>  end
>>
>>   colour is the Atribute, isn't it?
>
> Then that would need to be @colour.  You just created a brand new
> temporary variable.


@colour = Colour.create(...) would do the trick.  But the other way is
better :-)

A.
David H. (Guest)
on 2007-01-19 16:03
> - it don't understand why my code in the after_create() method did not
> work, the API says that ,,after_create() is called after Base.save on
> new objects that haven’t been saved yet (no record exists)", in the
> code:

A record doesn't have an ID until it's be saved.
So if you save the child before the parent, the parent_id column
(colour_id) will be zero by default.
askegg (Guest)
on 2007-01-19 17:29
(Received via mailing list)
P. Pantouffe wrote:
>
>   colour is the Atribute, isn't it?

The code is called after the record is created, but the current code
creates a new entry in the colour table, but does not tie it to the Car
record.

Strictly speaking, their is no "colour" attribute on the Car object -
there is only an association to a Colour object, so you need to pass a
Colour object not a string.

class Car < ActiveRecord::Base
  belongs_to :colour

  def after_create()
      self.colour = Colour.find_or_create_by_name('colour 1')
      self.save
   end

end
P. P. (Guest)
on 2007-01-19 18:12
thank u all for the info.
Best wishes!
Alan F. (Guest)
on 2007-01-19 18:14
P. Pantouffe wrote:
> thank u all for the info.
> Best wishes!


No problem,

Alan
This topic is locked and can not be replied to.