Ask A Question

Notifications

You’re not receiving notifications from this thread.

Episode Suggestion: Normalization

Chris Zempel asked in Site Feedback

I've identified a tendency in myself that I feel like, if overcome, would make me a considerably better developer and produce better software. Here I'll try to characterize/analyze it:

Description: I feel like my ability to expand the way I store and represent data in a db is hampered by my ability to perceive of more complex relationships in the application layer (aka, how the heck do I set up forms and controllers for this?).

Internal Tell: I'll feel subtly unhappy about the way my models are set up, but not really know what to do about it. I'll be staring at how I've set up the schema and identify that I actually need to move a concept out of a given table to become its own thing.

Here's a pretty clear-cut example to illustrate:

I'll have a User table that stores phone numbers. Soon after, the organizations they're a part of need to store those, too. So, I might end up adding a phone_number column to both.

class User < ApplicationRecord
  validates :phone_number
end 

class Organization < ApplicationRecord
  validates :phone_number
end

Pretty much at this point I might find myself adding a concern with the logic for phone numbers, then including that in the models that have them. Ok, the data's stored two places, but my application code can be changed in one place.

Well, guess what, I need to now validate the uniqueness of the phone numbers. So, either I've gotta write some more Ruby to validate uniqueness across all the tables, or if I'm already in production, need to worry about migrating all the data to a new phone_numbers table so I can validate uniqueness there.

Timing: This is where the issue of timing comes into play. Breaking out a PhoneNumber into its own model is a pretty obvious thing since it bit me in one of my first applications (like Addresses), but there are some more and subtler ones that I'm finding over time (like any time I end up needing to store a bunch of constants or abusing enums, always worth breaking those out into their own table).

Guess what I'm really talking about is normalization. But there's a dimension of timing to this:

  • finding some concept that needs to be broken out immediately
  • discovering a concept that will implicitly be required by the app in the future, but not actually needed yet

before/after you already have production data to worry about

The Fear: I subconsciously shy away from good normalization because dealing with fields_for, while doable, is still confusing. Like, imagining the mapping of a form_for attribute to a database column on a model is easy. Imagining that relationship, validations, directory setup with a phone_number broken out isn't so natural yet.

So, knowing that I have a tendency towards just taking the easy path, this brings up the question: how can I add more things to that easy path? And that means, being able to phrase elements of the real world in such a way that they're well-suited for Rails.

So that's the starting point: basic discovery, jotting down some attributes onto models, setting up the relationships between them, but then - how far and how soon should I normalize? What do I need to learn more deeply to expand the easy path? (db stuff, just read through/code through variety of situations, look at how people have broken out what they have and ask why).

I've identified what I consider an issue. Is it actually an issue, or just a process I need to go through, or are there areas I need to learn? Not sure really sure what the actual problem is, just that there is one (I've tried describing it here). So I definitely don't know what a good answer to it would look like.

I often find myself needing to create form objects and other kinds of stuff that I don't feel good about, but can't put words to. So then a separation between how I'd like to store data, and how I can nicely phrase that in MVC.

Once I stumble across a situation like this, I'll write it up in this thread

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 81,536+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.