Wikis Made Easy
Wikease is a Rails app that emulates many of the key features of Wikipedia. Users can create private or public wikis, purchase paid upgrades for their account, and assign collaborators to the wikis they own. This project introduced several key gems to facilitate advanced user authentication and online order processing.
Tools
Rails, Rspec, Devise, Pundit, Stripe, Redcarpet, Faker, Bootstrap, Atom, Ubuntu
Breakdown
The Devise gem is used for user authentication, with built-in email verification and input validation. It is used alongside Pundit to define member privilege levels (aka roles), namely member, premium member, and admin. Through these roles, premium or admin users are able to create private wikis that are only viewable to their owner or collaborators. Standard users may upgrade to premium users as a paid service facilitated through Stripe. For wiki authors, Redcarpet allows users to use Markdown for formatting their page content.
Working Together
The main challenge I encountered here was grappling with ActiveRecord associations. Since this was the first time I was working with them without “training wheels,” I continued to struggle figuring out how best to organize my associations between Users, Wikis, and Collaborations.
My initial thinking was that users would need a reference to their collaborators, so my early attempts involved adding this to my User model:
class User < ActiveRecord::Base
...
has_many :collaborators, class_name: 'User', source: :user, through: :collaborations
...
end
As it turns out, this was unnecessary. While it intuitively makes sense for a user to want to know about their collaborators, this isn’t how has_many :through
relationships work. The :through
model is strictly used to describe the connection between two models in contexts where a conventional :belongs_to
and :has_many
relationship wouldn’t make sense. In this case, a wiki does belong to a user, but not the other way around, or is a wiki exclusively owned by a single user in the context of a collaboration. Thus the Collaboration
model describes the activity the two other models are engaged in together, not a relationship in the direct sense.
Thus the challenge I encountered came down to confusing the colloquial implications of a Collaboration
with its functional application in Rails. I see now the importance of carefully naming such models to avoid this kind of confusion.
Conclusions
This project marked a second time when I stumbled in making sense of complex ActiveRecord associations, but in reviewing it and working with my mentor I am able to paint a clearer picture in my mind of how to work with them. Particularly with Rails, some of the challenge comes in suspending assumptions around a word or concept in favor of accepting how a particular language or framework does things. For better or worse, there are times when familiar concepts like “associations” or “scopes” are used to describe very different things than what you expect.