DEV Community

Joel Warrington
Joel Warrington

Posted on

Building a Ruby on Rails MVP.

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.

Subscription overview page

Buildings index page

New building page

New building page with validation errors

Unit show page

Unit listing show page, from the admin

Unit listing show page, viewed by the public

New inquiry page

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
Enter fullscreen mode Exit fullscreen mode
rails new homesuiteapartment
Enter fullscreen mode Exit fullscreen mode

from there, it's as simple as using the provided generators to scaffold the app.

bin/rails generate scaffold building name
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)