0

I have a class persons and a class subjects. at the moment they are not connected at all. As a user one can only chose subjects from a list and inspect them. Now I'd like to allow users to assign to subjects, thus the user class needs a list where it can store its subjects. ... and a table which maps subjects to persons.. (m to n)

I have not much experience with Ruby on Rails and I am afraid to destroy my application when trying to do this. So far I found out that there are commands to do that (sth. like $ rails generate migration AddSubjectsToPersons), but I can't find out what they do exactly, e.g.if it touches my model or controller classes.. In case that yes - is there something removed I wrote before?, if not - is it enough to add a field (a list) called lessons to my model and the connection to the db will be detected automatically?

chris
  • 247
  • 2
  • 5
  • 16

2 Answers2

1

The script rails generate migration creates a migration file that contains all commands to manipulate the database when you run it with rake db:migrate.
For example, you create a migration that adds the foreign key to the table and execute the migration. Then, you go to your model and put the correct active_record references between your two models, (belongs_to, has_many). After doing this steps, if you check your console rails console, and do something like

user = User.find(1)
user.subjects

The query should work flawless.
So basically, the migration generator scripts just manipulate the database. All the other changes must be made by changing code on your models.

MurifoX
  • 14,991
  • 3
  • 36
  • 60
  • the command has created a migration for me now, but the file is almost empty and it looks as if I had to write the table definition on my own. But how? `create_table :users_lessons do |t| t.references :person t.references :subject end`? In http://guides.rubyonrails.org/migrations they even don't explain what this t is.. :( and they say that "The references helper does not actually create foreign key constraints for you. You will need to use execute or a plugin that adds foreign key support." I am confused :( – chris Dec 11 '12 at 15:52
  • On your migration file, you have to manually type your table definition following some conventions. For example, if you put a `add_column :users, :subject_id, :integer`, this would create the column on your table, so `active_record` can make the queries successful. – MurifoX Dec 11 '12 at 16:09
0

I generated a migration file using the command rails generate migration CreatePersonsSubjects. The names are put together in alphabetical order (convention). The result of this command is an skeleton in which code can be entered to change database tables. This went to the "up" part:

create_table :persons_subjects, :id => false do |t|
      t.integer :person_id, :null => false
      t.integer :subject_id, :null => false
    end 

In the "down" part these actions can be reverted:

   drop_table :persons_subjects

Finally I added a field in the person class (and only to the person class, by the way. But one could/should also add a similar line to the subject). The name is convention too.

  has_and_belongs_to_many :subjects

The subjects can be used for example like this in the view:

<div>Courses taken:
  <ul>
    <% @person.subjects.each do |subject| %>
      <li><%= link_to subject.name, subject, :class => 'action' %></li>
    <% end %>
  </ul>
</div>
chris
  • 247
  • 2
  • 5
  • 16