Forum: Ruby on Rails has_and_belongs_to_many and collections management

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.
Justin Christian (Guest)
on 2006-03-29 15:17
(Received via mailing list)
Sorry for the big post. I'm having a lot of confusion when trying to
implement a simple model relationship that uses all the good things of
ActiveRecord.

I need to store some dinamic entries about knowledge of certain people
on
the database. A knowledge is measured with another table, with a range
of
possible values for a knowledge. This is a reduced schema of my
database:

create table people (
  id   int          not null auto_increment,
  name varchar(255) not null,
  primary key (id)
);

create table knowledges (
  id   int          not null auto_increment,
  name varchar(255) not null,
  primary key (id)
);

create table experiences (
  id   int          not null auto_increment,
  name varchar(255) not null,
  primary key (id)
);

create table experiences_people (
  person_id     int not null,
  knowledge_id  int not null,
  experience_id int not null
);

Let's insert some default values:

insert into knowledges (name) values ("Books");
insert into knowledges (name) values ("Music");
insert into knowledges (name) values ("Sports");

insert into experiences (name) values ("Bad");
insert into experiences (name) values ("Medium");
insert into experiences (name) values ("Good");

And this are my models for this application:

class Person < ActiveRecord::Base
  has_and_belongs_to_many :knowledges
end

class Knowledge < ActiveRecord::Base
  has_and_belongs_to_many :people
end

class Experience < ActiveRecord::Base
end

This is why I need for the user interface:

* During a user (person) creation, I need to display a page with a list
of
all possible knowledges and a dropdown list for each one (with, of
course,
all possible experience values).

* During a user (person) edition, I need the same as before, but of
course
with stored values for each knowledge already selected, and with the
possibility of change one or more values at the same time, storing that
new
values on the database (with substitution of old values, if they exists,
or
creating new entries for new values).

* During a knowledge view, a list with all people that has a value for
that
knowledge, displaying the experience for each one.

And this is what I started to code:

* For person creation, I have the following in people_controller.rb on
method "new":

class PeopleController < ApplicationController

def new
  @person = Person.new(@params[:person])
  @knowledges  = Knowledge.find(:all, :order => 'name').collect { |k| [
k.name, k.id ] }
  @experiences = Experience.find(:all, :order => 'name').collect { |k| [
k.name, k.id ] }
  if @request.post?
    @knowledges = @params[:knowledges]
    for knowledge in @knowledges
      new_knowledge = Knowledge.new
      ## In fact, I need to create a new entry in experiences_knowledges
with
      ## the knowledge id and the experience id selected. How can I do
that?
      @person.knowledges << knowledge
    end
    if @person.save
      flash['notice'] = 'Person was successfully created.'
      redirect_to :action => 'show', :id => @person.id
    end
  end
end

And this is my new.rhtml view:

<%= start_form_tag :action => "new" %>
<!--[form:people]-->

  <table>
    <tr>
      <td>Name:</td>
      <td><%= text_field("person", "name") %></td>
    </tr>
<% for knowledge in @knowledges %>
    <tr>
      <td><%= knowledge.name %></td>
      <td><%= select 'knowledges_ids', knowledge.id, @experiences, {
:include_blank => true } %></td>
    </tr>
<% end %>
  </table>
<%= end_form_tag %>

As you can see, there is a comment on the controller code where must be
the
creation of that entry. And I don't know how to add knowledge entry to @
person.knowledges collection. I have the same (but more difficult to me)
problem when I think in coding edit action, where I'll need to edit a
knowledge that is already on the collection.

And for the list of people that has a value for a certain knowledge, I
suposse that it's possible to use the 'people' accessor to get the
people
collection associated with the person object. But how can I get the
experience associated with that person and knowledge to display it?

Thanks in advance for reading to here. Any suggestion will be really
thankfull.
This topic is locked and can not be replied to.