ruby-on-railsruby-on-rails-5database-schematable-relationships

How to correctly maintain database schema in rails?


I have schema like this:

create_table "grades", force: :cascade do |t|
    t.integer "cls"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "post_grades", force: :cascade do |t|
    t.integer "post_id"
    t.integer "grade_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "posts", force: :cascade do |t|
    t.integer "user_id", null: false
    t.string "title"
    t.text "content"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

create_table "user_grades", force: :cascade do |t|
    t.integer "user_id"
    t.integer "grade_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

In this schema grades, posts and users all are related to each other.

So my first question: Is it correct way of doing this?

Suppose one of user added grade 4 (cls = 4) in his column and another user added same grade. Now I have same value of cls in grade table for two different grade ids.So is there any data redundancy in this schema?


Solution

  • As I got your task, you can go with such solution:

    1. grades -> no references (as it is right now)
    2. user_grades (conventional way to name this table would be grades_users... alphabetical order and both in plural) -> user_id, grade_id (as it is right now)
    3. You don't need post_grades. It's redundant
    4. posts -> grade_id, user_id (if you need author)

    Your schema.rb will look smth like:

    create_table "users", force: :cascade do |t|
      ...
    end
    
    create_table "grades_users", force: :cascade do |t|
      t.integer "user_id"
      t.integer "grade_id"
      ...
    end
    
    create_table "grades", force: :cascade do |t|
      ...
    end
    
    create_table "posts", force: :cascade do |t|
      t.integer "user_id", null: false
      t.integer "grade_id", null: false
      ...
    end