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