Skip to content

Unified access control, folder structure, aliases mechanism for all sorts of notes #39

@x-tropy

Description

@x-tropy

Since any note should belong to a folder, any note can have an aliase, and any note has an access control model, these features in common should be abstracted away in Rails. Some common approaches:

1. Polymorphic Models

Folder Association

Define a Folder model, and make the association polymorphic if multiple models need to belong to folders:

# app/models/folder.rb
class Folder < ApplicationRecord
  has_many :folderables, as: :folderable, dependent: :destroy
end

# app/models/concerns/folderable.rb
module Folderable
  extend ActiveSupport::Concern

  included do
    belongs_to :folderable, polymorphic: true
  end
end

Alias

An alias can also be modeled using a polymorphic association:

# app/models/alias.rb
class Alias < ApplicationRecord
  belongs_to :aliasable, polymorphic: true
end

# app/models/concerns/aliasable.rb
module Aliasable
  extend ActiveSupport::Concern

  included do
    has_one :alias, as: :aliasable, dependent: :destroy
    accepts_nested_attributes_for :alias
  end
end

Access Control

You can use a role-based model or a simple ownership model to handle access control:

# app/models/access_control.rb
class AccessControl < ApplicationRecord
  belongs_to :access_controllable, polymorphic: true

  enum access_level: { public: 0, private: 1, restricted: 2 } # Example levels
end

# app/models/concerns/access_controllable.rb
module AccessControllable
  extend ActiveSupport::Concern

  included do
    has_one :access_control, as: :access_controllable, dependent: :destroy
    accepts_nested_attributes_for :access_control
  end
end

2. Applying the Concerns

Use these concerns in your Note model:

# app/models/note.rb
class Note < ApplicationRecord
  include Folderable
  include Aliasable
  include AccessControllable

  # Other note-specific logic...
end

3. Database Migrations

Run migrations to add polymorphic fields and other attributes:

class CreateFolders < ActiveRecord::Migration[6.1]
  def change
    create_table :folders do |t|
      t.string :name
      t.timestamps
    end
  end
end

class CreateAliases < ActiveRecord::Migration[6.1]
  def change
    create_table :aliases do |t|
      t.string :name
      t.references :aliasable, polymorphic: true, index: true
      t.timestamps
    end
  end
end

class CreateAccessControls < ActiveRecord::Migration[6.1]
  def change
    create_table :access_controls do |t|
      t.references :access_controllable, polymorphic: true, index: true
      t.integer :access_level, default: 0
      t.timestamps
    end
  end
end

4. Usage

Create a note with all these common features:

@folder = Folder.create(name: "Personal Notes")
@note = Note.create(
  title: "My Note",
  folder: @folder,
  alias_attributes: { name: "Shortcut Name" },
  access_control_attributes: { access_level: :restricted }
)

Benefits

  • Reusability: The concerns can be reused in other models like Article or Task.
  • Decoupling: Separates common logic from the Note model.
  • Extensibility: You can easily add new features like tagging or versioning.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions