Starting my Rails project, I wanted to create an app where users can call native speakers of a language of their choice in order to practice their language skills.
In order to set up the relationships, I set it up so that the app would have a self-join table “Users”, with two types of users for a call: “Callers” and “Speakers”. A user could be both a caller and a speaker, depending on if they are a native speaker for that particular language.
A “caller” would be the one making a call to the foreign language “speaker”. There is a “Calls” join table that includes the scheduled time of the call and its duration. The relation between Users and Calls looked like this:
class Call < ApplicationRecordbelongs_to :languagebelongs_to :speaker, class_name: "User"belongs_to :caller, class_name: "User"
...end
and:
class User < ApplicationRecord...#as a callerhas_many :speaker_calls, foreign_key: "speaker_id", class_name: "Call"has_many :speakers, through: :speaker_calls, class_name: "User"#as a speakerhas_many :caller_calls, foreign_key: "caller_id", class_name: "Call"has_many :callers, through: :caller_calls, class_name: "User"...end
It was a little challenging at first trying to lay out the logic behind it, but once the tables were set up, it turned out great.
For the login of the app, I had users sign up using their email, username, name, and password. From their usernames, I set up a slug so that the user’s and languages wouldn’t show the URL, making it more user-friendly. One of the requirements was to use a third-party login option, using OmniAuth. The way I had set it up with the validations requiring username, name, etc, it would make it difficult to use the slug methods that I was currently using for the usernames and the languages.
To get around that, I built a method that turned the first part of the user’s email into the slug that would be used for the app. Since it would be part of the URL, it cannot contain any periods(.
), which can be common for email addresses.
module UsersHelperdef slugself.username = self.email.split('@')[0].downcase.gsub(".", "")endend
I plan on continuing to work on the app further after turning it in as the project, adding more features to it as well as an admin signup route so that admins are able to create, edit, and delete languages.
It was a great learning experience overall! I’m very excited to keep working on it and to learn more in the next phase of the program!