Has_and_belongs_to_many and collections management


#1

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” %>

<% for knowledge in @knowledges %> <% end %>
Name: <%= text_field("person", "name") %>
<%= knowledge.name %> <%= select 'knowledges_ids', knowledge.id, @experiences, { :include_blank => true } %>
<%= 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.