Creating controllers and views for a has_many :through relationship in Rails 3

Randy Burgess picture Randy Burgess · Nov 9, 2011 · Viewed 8.6k times · Source

There are many tutorials that show you how to create the model instructions for a has_many :through relationship in Rails, but there doesn't seem to be many articles related to the process of setting up forms to create and edit these relationships. I am seeking some assistance (or good examples) of how to create an interface that will allow users to manage these types of relationships in a Rails app.

Here's the scenario:

I have Users, Relationships, and Athletes. A User can have a Relationship with an Athlete in a variety of roles: Coach, Mentor, Parent, or Fan.

Here are my models:

class User < ActiveRecord::Base
  has_many :relationships
  has_many :athletes, :through => :relationships
end

class Athlete < ActiveRecord :: Base
  has_many :relationships
  has_many :users, :through => :relationships
end

class Relationship < ActiveRecord :: Base
  belongs_to :users
  belongs_to :athletes
end

So, the next step is to build the views and controllers that allows me to create a User-to-Athlete relationship (with a coach, parent, etc role), edit the relationship, or destroy the relationship.

Ultimately, my aim is to have a scenario where Users can create Athletes and choose the associated Relationship.

Unfortunately, I can't find any specific tutorials or references that gives me much more than the model instructions or the example for a has_many relationship.

If anyone has a link or example that can solve this problem at a simple level, I should be able to customize the rest.

Answer

Batkins picture Batkins · Nov 9, 2011

The relationship you have here between your User and Athlete model is essentially a has_and_belongs_to_many relationship (HABTM). By going back and forth with you it seems you're confused about what the best way to create these relationships would be.

A good place to start reading would be in the documentation for ActiveRecord's Associations, specifically the documentation for HABTM relationships.

You're model setup is fine. Now that you have your HABTM relationship setup, here's what you can do. Let's assume both your Athlete and User model are very simple and have nothing but a name attribute, which is a string. You can now do code like this (this is console output from the rails console):

User.create(:name => "Jeff")
usr = User.first
=> #<User id: 1, name: "Jeff">
usr.athletes
=> []
atl = usr.athletes.create(:name => "Mike")
=> #<Athlete id: 1, name: "Mike">

The line above will create a user with name Mike, and automatically create a relationship entry with the appropriate attributes to link the two. So now if you call this:

usr.athletes
=> [#<Athlete id: 1, name: "Mike">]

Now if you wanted to allow the user to dictate what the relationship is between themselves and an Athlete upon Athlete creation, you could setup your Relationship class to have a relation field of type string, and when creating the relationships (as I just displayed above), you can then do something like this:

rel = usr.relationships.where(:user_id => usr.id, :athlete_id => atl.id).first
=> #<Relationship id: 1, user_id: 1, athlete_id: 2, :relation => nil>
rel.relation = "Friend"
rel.save
=> #<Relationship id: 1, user_id: 1, athlete_id: 2, :relation => "Friend">

Hopefully this is more helpful than my original answer. Let me know if you have any questions. And definitely be sure to look at the ActiveRecord Associations documentation I mentioned above.