Implementing User Collaboration

Eli Huebner
3 min readApr 23, 2021

At an interview recently, I was asked to show off an app that I had already made, and then to explain how I would implement various changed to the functionality of the app. The project I ended up showing off was an app for costume designers, written with Ruby on Rails with an MVC (Model-View-Controller) architecture. Once signed in, users create listings for costumes, with a description and note about what role the costume is for. Each costume is associated with an actor, either an existing one or one created when the costume form is submitted. Users can view a list of their costumes or a list of the actors they have created costumes for, and existing costumes can be edited. Users can only see their own costumes, and must be logged in to use the app at all. It’s not the most complicated of apps, having been built to satisfy a project requirement at Flatiron School as part of the Software Engineering Bootcamp.

The models in the app are Costumes, Actors, and Users. I used ActiveRecord to manage the database and model associations. A user has_many :costumes, and has_many :actors, through: :costumes . A costume belongs_to :user and belongs_to :actor, while an actor has_many :costumes, and has_many :users, through: :costumes . The task at the interview was to allow costumers from the same theatre to see each other’s costumes and possibly collaborate.

Now, I will make several assumptions before beginning to make this a little easier. A costume instance can only belong to one theatre (no sharing), and for now a user cannot change jobs to work at another theatre.

The first thing we need to do is create another model: Theatre. The theatres table will have a column for name:string . We will also create migrations for both users and costumes to add columns for theatre_id . We will add to user.rb that the resource belongs_to :theatre , while a theatre has_many :users, :costumes . We will also create a many-to-many relationship between actors and theatres: actor has_many :theatres, through: costumes and theatre has_many :actors, through:costumes . Now, our models should be all set.

./app/models/costume.rb
class Costume < ApplicationRecord
belongs_to :user
belongs_to :actor
belongs_to :theatre
...
end
./app/models/actor.rb
class Actor < ApplicationRecord
has_many :costumes
has_many :users, through: :costumes
has_many theatres, through: :costumes
...
end
./app/models/user.rb
class User < ApplicationRecord
has_many :costumes
has_many :actors, though: :costumes
belongs_to :theatre
...
end
./app/models/theatre.rb
class Theatre < ApplicationRecord
has_many :users, :costumes
has_many :actors, through :costumes
...
end
./db/migrate/create_theatres.rb
class CreateTheatres < ActiveRecord::Migration[6.0]
def change
create_table :theatres do |t|
t.string :name
end
end
end
./db/migrate/add_theatre_to_costumes.rb
class AddTheatreToCostumes < ActiveRecord::Migration[6.0]
def change
add_column :costumes, theatre_id
end
end
./db/migrate/add_theatre_to_users.rb
class AddTheatreToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, theatre_id
end
end

After running rails db:migrate , our models should be ready to go. When signing up, a user should be able to select or enter a theatre, which gets set at the theatre to which they belong. When creating a new costume, we will set costume.theatre = current_user.theatre .

Now we need to change our controllers. These changes are actually pretty minor. At the moment, when pulling lists of costumes or actors, we are using current_user.costumes and current_user.actors. We will change those lines wherever we find them to current_user.theatre.costumes and current_user.theatre.actors . We have not expanded our list to everything that belongs to the theatre, rather than to the user. We might still limit editing rights to resources that belong to current_user, and it would take a bit more work if we wanted an option to select which coworkers have editing rights and which do not.

--

--

Eli Huebner

I taught high school history for 4 years, before pivoting to software development in search of something more creative.