Home > Net >  How to model a Post object that could be assigned to 1 or more levels
How to model a Post object that could be assigned to 1 or more levels

Time:12-31

I have a post model

class Post < ApplicationRecord
    belongs_to :account
end

The migration looks like:

class CreatePosts < ActiveRecord::Migration[7.0]
  def change
    create_table :posts do |t|
      t.integer :account_id, null: false
      t.string :title, null: false
      t.string :content, null: false

      t.timestamps
    end
  end
end

Now when I display a list of these posts, I only display them based on the permission of the user.

class Level< ApplicationRecord
end

class CreateLevels < ActiveRecord::Migration[7.0]
  def change
    create_table :levels do |t|
      t.integer :account_id, null: false
      t.string :name, null: false         

      t.timestamps
    end
  end
end

So say I have user permissions modelled as Levels:

Level 1
Level 2
Level 3

So each time a Post is created, it will be assigned to 1 more of these levels.

When a user who has level 2 views the list of posts, the user will see ONLY posts that are associated with Level 2.

I guess the table would look like:

- post_id
- level_id
- timestamps

So a Post could belong to 1 more more levels, but I don't think the same post_id will ever be associated to the same level_id in the system.

What type of association would best describe this in Rails/ActiveRecord?

If someone could help tweak my migration and add the appropriate associations to the model.

CodePudding user response:

The following is a slightly hidden requirement:

So a Post could belong to 1 more more levels, but I don't think the same post_id will ever be associated to the same level_id in the system.

It should be possible, so it is a requirement. This means you will need a many-to-many relation. On the model, you will use a has_and_belongs_to_many.

More information can be found on this Stack Overflow question specifically asking about many-to-many relationships: Creating a many to many relationship in Rails

CodePudding user response:

I would probably model this like so:

Migrations

create_table :users do |t| 
  t.string :username, null: false
end 
create_table :posts do |t| 
  t.references :author, foreign_key: { to_table: :users }
  t.string :title, null: false
  t.string :content, null: false
end 
create_table :levels do |t| 
  t.string :name, null: false
  t.timestamps
end 
create_table :post_levels do |t| 
  t.references :level
  t.references :post
  t.timestamps
end 
add_reference(:users, :level)

Models

class User 
  belongs_to :level 
  has_many :authored_posts, class_name: 'Post', foreign_key: :author_id
  has_many :viewable_posts, through: :level, source: :posts
end 

class Post 
  belongs_to :author, class_name: 'User'
  has_many :post_levels
  has_many :levels, through: :post_levels
end 

class Level 
    has_many :users 
    has_many :post_levels
    has_many :posts, through: :post_levels
end 

class PostLevel
    belongs_to :level
    belongs_to :post 
 
    # make sure a post can only belong to a level one time 
    validates :post_id, uniqueness: {scope: :level_id}
end 
  • Related