Forum: Ruby on Rails Trying to display data from two tables

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.
724a9d1d0244e08cb4be518c88648d9f?d=identicon&s=25 Andy Park (prot)
on 2006-01-04 04:25
Alrighty folks, I'm really trying here, and want to succeed with Ruby on
Rails.

I'm trying to display data that is linked from two tables using the
Active Record naming conventions, as described in Agile Web book.

The stripped-down basics;

Database

drop table if exists people;
CREATE TABLE `people` (
  `id` int(6) NOT NULL auto_increment,
  `lastname` varchar(30) NOT NULL,
  `personkind_id` int(6) NOT NULL default '23',
  PRIMARY KEY  (`id`)
)

drop table if exists person_kinds;
CREATE TABLE `person_kinds` (
  `id` int(6) NOT NULL auto_increment,
  `kind` varchar(30) NOT NULL,
  PRIMARY KEY  (`id`)
)

###########################

Using ruby script/generate scaffold

Controllers;

class PersonAdminController < ApplicationController

def list
    @person_pages, @people = paginate(:people, :order_by =>'lastname',
:per_page => 10)
    @person_kinds = PersonKind.find_all
end

class PersonKindAdminController < ApplicationController


###########################

Models

class Person < ActiveRecord::Base
  belongs_to :person_kind
end


class PersonKind < ActiveRecord::Base
  has_many :people
end

###########################

list.rhtml

<h1>People by Field</h1>
<table border="1">
 <tr>
  <td width="33%"><p align="center"><i><b>Last Name</b></i></td>
  <td width="33%"><p align="center"><i><b>Kind</b></i></td>
 </tr>

 <% @people.each do |person| %>
  <tr>
   <td><%= link_to person.lastname, :action => "show", :id => person.id
%></td>
   <td><%= person.firstname %></td>
   <td><%= person.person_kind.kind %> </td>
  </tr>
 <% end %>
</table>
<p><%= link_to "Add New Person", :action => "new" %></p>

##############################

The <%= person.person_kind.kind %> line in the list.rhtml is what is
causing my brain to turn to tapioca.

I really thought that that would work. I know this is very basic Rails
stuff, but I'm stuck. Any help would be greatly appreciated.

Kindest regards.
C8a634a01a2c4508360874bff7fb1a7f?d=identicon&s=25 Kevin Olbrich (Guest)
on 2006-01-04 05:16
Andy Park wrote:
>
> def list
>     @person_pages, @people = paginate(:people, :order_by =>'lastname',
> :per_page => 10)
>     @person_kinds = PersonKind.find_all
> end

try adding an :include=>:kind to the paginate function.
724a9d1d0244e08cb4be518c88648d9f?d=identicon&s=25 Andy Park (prot)
on 2006-01-04 05:47
Kevin Olbrich wrote:

> try adding an :include=>:kind to the paginate function.

Nope it generates the following erorr

"Association was not found; perhaps you misspelled it?  You specified
:include => :kind"

If I just use

<%= person.person_kind.kind %>

in the list.rhtml, as in my first post, I get the following erorr,

"You have a nil object when you didn't expect it!
The error occured while evaluating nil.kind"

I thought that the belongs_to & has_many took care of this.
17acfbd3a05cfb59e0543235cc0a813b?d=identicon&s=25 joshua (Guest)
on 2006-01-04 05:50
It looks like you are missing an underbar.  Try 'person_kind_id' as the
column name in people.

Andy Park wrote:
> Database
>
> drop table if exists people;
> CREATE TABLE `people` (
>   `id` int(6) NOT NULL auto_increment,
>   `lastname` varchar(30) NOT NULL,
>   `personkind_id` int(6) NOT NULL default '23',
>   PRIMARY KEY  (`id`)
> )
>
> drop table if exists person_kinds;
> CREATE TABLE `person_kinds` (
>   `id` int(6) NOT NULL auto_increment,
>   `kind` varchar(30) NOT NULL,
>   PRIMARY KEY  (`id`)
> )
724a9d1d0244e08cb4be518c88648d9f?d=identicon&s=25 Andy Park (prot)
on 2006-01-04 06:03
joshua wrote:
> It looks like you are missing an underbar.  Try 'person_kind_id' as the
> column name in people.


I thought this as well, however, the following works just fine on my
edit.rhtml

<select name="person[personkind_id]">
<% @person_kinds.each do |personkind| %>
<option value="<%= personkind.id %>" <%= ' selected' if personkind.id ==
@person.personkind_id %>>
<%= personkind.kind %>
</option>
<% end %>
</select>

Although, I should try 'person_kind_id' as the column name just to rule
it out.

Thanks for taking the time to look at it.
17acfbd3a05cfb59e0543235cc0a813b?d=identicon&s=25 joshua (Guest)
on 2006-01-04 06:14
Your code example works because it has nothing to do with how
ActiveRecord guesses names. AR uses the convention of adding _id to a
model name to get the foreign key. On the one hand you have a model
named "person_kind", but on the other you are using the name
"personkind_id" for the foreign key. You should have a fk called
"person_kind_id" to follow AR's convention, or explicitly specify the
non-standard foreign key in the association method in your model class
with :foreign_key => "personkind_id"

Andy Park wrote:
I thought this as well, however, the following works just fine on my
> edit.rhtml
>
> <select name="person[personkind_id]">
> <% @person_kinds.each do |personkind| %>
> <option value="<%= personkind.id %>" <%= ' selected' if personkind.id ==
> @person.personkind_id %>>
> <%= personkind.kind %>
> </option>
> <% end %>
> </select>
>
> Although, I should try 'person_kind_id' as the column name just to rule
> it out.
11a6596e5453443c025f2d23a5d06027?d=identicon&s=25 Richard Downe (runrunshaw)
on 2006-01-04 06:48
Andy Park wrote:
>
>
> Database
>
> drop table if exists people;
> CREATE TABLE `people` (
>   `id` int(6) NOT NULL auto_increment,
>   `lastname` varchar(30) NOT NULL,
>   `personkind_id` int(6) NOT NULL default '23',
>   PRIMARY KEY  (`id`)
> )
>
> drop table if exists person_kinds;
> CREATE TABLE `person_kinds` (
>   `id` int(6) NOT NULL auto_increment,
>   `kind` varchar(30) NOT NULL,
>   PRIMARY KEY  (`id`)
> )
>
> ###########################
>
I have to agree with Joshua on this.  It seems as if the issue lies in
the foreign key name.  I would definitely try renaming 'personkind_id'
to 'person_kind_id' so that AR can find the link between the two tables.
Furthermore, check out page 230 in the Agile Web book.  It gives some
good info on how AR actually creates methods for you based on table
relationships.

So for example, if you used the find() method to find all of the people
in your DB, you could get the data (attributes) related to each person
from the other table.  I'm not really sure what your app is about but AR
can handle all of this for you based on the proper naming of the foreign
key, just double check page 230 in the book.
724a9d1d0244e08cb4be518c88648d9f?d=identicon&s=25 Andy Park (prot)
on 2006-01-04 06:49
joshua wrote:
> Your code example works because it has nothing to do with how
> ActiveRecord guesses names. AR uses the convention of adding _id to a
> model name to get the foreign key. On the one hand you have a model
> named "person_kind", but on the other you are using the name
> "personkind_id" for the foreign key. You should have a fk called
> "person_kind_id" to follow AR's convention, or explicitly specify the
> non-standard foreign key in the association method in your model class
> with :foreign_key => "personkind_id"

Joshua,

Spot on mate. Thankyou so much.

Changing "personkind_id"  to "person_kind_id" solved the problem.

Also, thankyou for taking the time explaining why the selection box
would work.

Once I made that change, I also had to change my selection box too

<select name="person[person_kind_id]">
<% @person_kinds.each do |person_kind| %>
<option value="<%= person_kind.id %>" <%= ' selected' if person_kind.id
== @person.person_kind_id %>>
<%= person_kind.kind %>
</option>
<% end %>
</select>
724a9d1d0244e08cb4be518c88648d9f?d=identicon&s=25 Andy Park (prot)
on 2006-01-04 06:53
richard downe wrote:

> I have to agree with Joshua on this.  It seems as if the issue lies in
> the foreign key name.  I would definitely try renaming 'personkind_id'
> to 'person_kind_id' so that AR can find the link between the two tables.
> Furthermore, check out page 230 in the Agile Web book.  It gives some
> good info on how AR actually creates methods for you based on table
> relationships.
>
> So for example, if you used the find() method to find all of the people
> in your DB, you could get the data (attributes) related to each person
> from the other table.  I'm not really sure what your app is about but AR
> can handle all of this for you based on the proper naming of the foreign
> key, just double check page 230 in the book.

I'll check page 230 first thing in the morning, thankyou Richard.

I made the assumption that the selection box was using Active Record in
the same manner.
This topic is locked and can not be replied to.