Hey there 👋,
It's been 2 weeks since I announced the new project I'm working on: HomeSuiteApartment, a tool to manage properties.
Today, I'll be sharing an update update on the progress so far, what's next, and share some developer insights for your own Ruby on Rails project! If you'd prefer, I've also uploaded a video walking through the product.
Progress made so far
I've been able to build out:
- an integration with Stripe to offer subscription plans
- CRUD routes for buildings and units
- CRUD routes to list a unit (at the moment only on HomeSuiteApartment, eventually on other rental listing marketplaces) and send inquiries
A lot of the pages have placeholder content at the moment, which I'll be fleshing out, but the intended workflow is almost done.
An overview on my workflow
Ruby on Rails, in my opinion, is the most productive full-stack web framework to-date.
I'd highly recommend reading up on the Rails Doctrine, it really explains why Ruby on Rails came to be what it is today and how it's surpassed other frameworks.
To get started with Ruby on Rails, it was as simple as generating a new project, using the rails
command line.
gem install rails
rails new homesuiteapartment
from there, it's as simple as using the provided generators to scaffold the app.
bin/rails generate scaffold building name
This generates a database migration, model, route definition, controller and views, as well as tests if you've configured that. In all of a few minutes, you've got a 'working' application. In most cases, you'll need to do more, but the scaffold generator alone seems like cheating.
One of my favourite things about using generators, is that it's quite easy to customize, especially if you've implemented other gems for authorization and need to change the controller template.
Thankfully, Ruby and Ruby on Rails are well established, and have a large community building 'packages', known as gems, similar to node packages.
Ruby on Rails is really just a collection of Gems which work very well together, such as ActiveRecord, ActiveModel, ActionView and much more.
Gems are a helpful tool to easily add new functionality to your Ruby on Rails application, and is especially helpful when building an MVP so you don't need to build everything from scratch.
Some of my favourite gems
Authentication
As mentioned in my previous blog post, On the road to ramen profitability 🍜 💸, I mentioned that I'm using devise. It's one of the most popular open-source authentication solutions for Rails.
I highly recommend it, as it's very configurable, and there are many plugins which I'll implement in the future, such as OmniAuth.
One pitfall though, if you've never worked with Ruby on Rails, I recommend avoiding it and starting with a simple authentication system from scratch.
Authorization
If you're unfamiliar with authorization, it's very different from authentication. Read the Authentication vs. Authorization article from auth0 to learn more, but in essence:
authentication is the process of verifying who a user is, while authorization is the process of verifying what they have access to.
There are a few gems which implement different strategies, such as CanCanCan and Pundit.
My favourite gem for implementing authorization strategies is ActionPolicy. It's very similar to Pundit, but is more extensible and isn't as barebones.
It's as simple as adding a new policy, and implementing the methods corresponding to the actions in your controller. In the example below, we have the UnitPolicy
which will be used in the UnitsController
. The organization_user?
is a method which will return true
if the user is part of the organization they're trying to access.
At the moment, most of my policies are very simple and simply check that a user is part of an organization, however, in the future it'll be easy to add permissions, roles, etc.
class UnitPolicy < ApplicationPolicy
def index?
organization_user?
end
def new?
organization_user?
end
def create?
organization_user?
end
def show?
organization_user?
end
def edit?
organization_user?
end
def update?
organization_user?
end
def destroy?
organization_user?
end
private
relation_scope do |relation|
relation.where(organization: organization)
end
params_filter do |params|
params.permit(
:name
)
end
end
Views and Components
Out of the box, Ruby on Rails uses erb templating to build views, and partials. In Rails convention over configuration fashion, it's best to have views which correspond to your get
actions, and you'll see these views get generated when you run the scaffold generator.
However, you might want to re-use and share code between views, and at first most would reach for partials, or if you're brave enough, think that implementing a React frontend will make this better for you, but there's a better solution.
- ViewComponent is a framework/gem for creating reusable, testable & encapsulated view components, built to integrate seamlessly with Ruby on Rails.
- ViewComponent::Form provides an ActionView FormBuilder, so you can easily use ViewComponent components in your form helpers
I recommend giving these two gems a try, to , and helps with the composability that one might want,
These gems are both great at reducing the complexity and maintainability of partials, and allows for better composability, something which can be difficult in ERB templating. As mentioned previously, I've seen a lot of people reach for React frontends to solve this problem, and I think it's the wrong approach for a few reasons. If you're interested in that topic, let me know and I can publish an article going in-depth there.
Code formatting and linting
I highly recommend adding standardrb to your project. Under the hood it uses rubocop (A Ruby static code analyzer and formatter) and doesn't require any configuration - that's what makes it so powerful.
When building an MVP, you should spend the least amount of time working on things which don't directly provide value to what you're building. Linting is not a feature of your product.
When the time comes that I want to be picky about my formatting and linting rules, I'll likely pull out standard and write my own https://github.com/rubocop/rubocop rules, but in the meantime this is more than good enough.
Testing
Similar to linting and formatting, testing isn't really a feature. Some would highly argue against shipping code without rock-solid tests. But it really slows you down if you're hunting absolute coverage.
In my own projects, I'll use rspec with shoulda-matchers alongside FactoryBot to quickly and easily write simple tests.
For the most part, I won't add many more tests than what's included in the basic scaffold generator. Not to say I won't write tests, but covering every code path is not nescessary here. Happy path is good enough.
Running jobs
Ruby on Rails provides a common interface for scheduled jobs called ActiveJob, but there isn't a single job runner in the scene. There are gems such as resque and sidekiq but both of these gems are dependent on adding Redis.
These days, I'll be using solid_queue as it's a simple solution which uses your existing SQL database.
Clean code
To avoid a lot of the boilerplate with Ruby on Rails controllers, I recommend the responders gem. Also it's used by devise under the hood!
What's next?
Thanks for sticking to the end, I hope I've shared a few gems that will help you build your own Ruby on Rails application if you decide to do so.
As for me, I'll continue building out HomeSuiteApartment, and in the next 2 weeks will mostly focus on:
- polishing pages, such as the subscription overview and unit listing page
- adding functionality to see inquiries, and book viewings from inquiries
See you in 2 weeks, for the next update!
Top comments (0)