The final capstone project of The Odin Ruby on Rails Learning Track. The project involves building a facebook clone with some of the core features of the platform – users, profiles, “friending”, posts, news feed, comments, likes and notifications. The full assignment consists of 18 requirements along with 4 "extra credit".
Visit Fakebook and use a demo login (email: fred@flintstone.com, password: password) to tour the site with demo functionality. Otherwise, sign up for a new account or log in with real facebook.
HEADS UP: Heroku server may need up to 30 sec to fire up a dyno. Be patient! :)
Authentication check prevents a non-signed in user from seeing anything else except the log in page.
Log in/sign up is done with Devise including Facebook log in/sign up using OmniAuth with Devise.
The process of implementation of Facebook OAuth2 strategy for OmniAuth is very well documented on their GitHub page, there is also a Facebook example on Devise's page, without mentioning plenty of tutorials, youtube videos and blogs showing how to do it. Here are my findings while building this feature:
omniauth-facebook
it will come with an omniauth
generic gem. In my case it lead to an Error: Not found. Authentication passthru.
It took me some time to find a solution here. If you're struggling like me, please be my guest. A onetime welcome email is sent to a new user during sign up using letter opener
in test and development and SendGrid
in production (edit: my SendGrid account was disabled, so ActionMailer is configured to use Gmail).
Fakebook is made to have a close look to Facebook (obviously, with less content and features). To achieve this, styling was done using Tailwind 2.0. IMHO, it's the most close replica of original Facebook I've seen.
If you haven’t heard of Tailwind CSS yet, it is a CSS framework filled with a lot of preset CSS classes, which you can apply to your HTML elements, without the need to write custom CSS for them most of the time!
It took me some time to figure out how to set it up, because I encounted a series of problems like
Error: PostCSS plugin tailwindcss requires PostCSS 8
, so I needed to install it with compat
channel.
Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (88)
, so make sure that your Node package is updated and it's 12+ and 15- otherwise you'll have problems as well, because node-sass does not support Node 15 (runtime **) currently and it will come with when v5 is published to NPM.
If you notice, like me, that the style didn’t change even after you have added some classes, try open terminal and run ./bin/webpack-dev-server
alongside with rails server so that the styling can be refreshed.
Despite all of these headaches and after making projects with Bootstrap, Bulma, Materialize, I can definitely tell that I'm a big fan of Tailwind. That’s it. Go read the Tailwind docs to find out more about this awesome CSS framework and style your app to your heart's content.
The application, by default, runs on PostgreSQL, using the default role name - same as the operating system user. So, you should either create a database user with the same username, or tell the application to use your custom database access info via the config/database.yml
configuration file.
If you want to play with the app locally, make sure you have Rails and Git installed on your machine
Clone the repo to your local machine:
$ git clone [email protected]:Pandenok/fakebook.git
Then, install the needed gems:
$ bundle install
Next, migrate the database:
$ rails db:migrate
If you want to load sample functional users to mess with, use seeds:
$ rails db:seed
To create an application.yml
file where you can safely store environment variables, run
$ bundle exec figaro
At this point you should be able to run the tests
$ rspec
Finally, on root path run a local server:
$ rails server
Open browser to view application:
localhost:3000
The primary challenge was configuring user associations, given that, in a symmetrical, Facebook-style relationship, a user can be either a user requesting a friendship or a user receiving a friendship request. There are many different ways to form a bi-directional friendship model, and the way I built it is for sure far away from perfection. But totally working. And the most important thing it works as I wanted it to work!
The FriendRequest status starts with enum "pending" state, which it remains for both users until the requested user accepts the request. Doing it this way takes away the need for callbacks or reverse association for the other friend. The most important thing it keeps the association methods intact, including implicit association creation: user.friends
! That's perfect, but what I want is to also be able to go in the other direction (kinda friend.friends
). This was a pain to figure out how to write a join table that references two users reciprocally: by using the -> { ... } block, we can pass in the instance of user and insert any typical Relation methods we would normally use when writing ActiveRecord queries. The final result you can see in my User model.
I have had a great experience so far with Rails, this project is not an exception, it helped me to get to grips with more complicated aspects. I really enjoyed doing this project and I hope it showcases some of Rails skills, even if not I personally definitely benefited from learning while doing it: so many things are a lot more clear to me now after finishing this app! I really felt the lack of Javascript in this project (e.g., for liking or commenting, or modals for creating/editing posts). However I think I found a nice work around for some things, like dropdowns menus on hover, editing of comments in place or profile's preview on click which helped to improve UX. From UI point of view, I relied on fantastic Tailwind 2.0, and I think it was worth it. I'm definitely proud of creating a very close clone to original website. There are still many things to do, but I decided to cut some features from the application in order to move on with The Odin Project. You can see them in the next Pipeline section.
If you've made it through reading all this, there is nothing else to do than to head over to Fakebook.