Hi all. The name is Daveyon and I’m a huge fan of Basecamp becuse of its quirky look/design and how their DOM element is structured. I’ve learnt a lot by examine their DOM and network requests which I then piece together to make my rails app. I work as a full-time PHP/Node developer so I have no one to share ideas with. One thing I did noticed was Basecamp use of bucket and recordings. I never paid it any mind up until recent where some mentioned Delegated types on Youtube.
I think I got my head around it but I need some advice here. Let’s use Basecamp’s todo as an example but mine is called Task
. Here’s my actual code:
class Bucket < ApplicationRecord
belongs_to :account
belongs_to :bucketable, polymorphic: true
has_many :recordings, dependent: :destroy
has_many :tasklists, through: :recordings, source: :recordable, source_type: 'Tasklist'
has_many :tasks, through: :recordings, source: :recordable, source_type: 'Task'
has_many :tasksets, through: :recordings, source: :recordable, source_type: 'Taskset'
has_many :fields, through: :recordings, source: :recordable, source_type: 'Field'
def record(recordable, creator: Current.person, account: Current.account, children: nil, parent: nil, options: {})
transaction do
recordable.save!
options.merge!(recordable: recordable, parent: parent, creator: creator)
recordings.create!(options).tap do |recording|
Array(children).each do |child|
record child, creator: creator, account: account, parent: recording
end
end
end
end
def incinerate(record)
transaction do
record.destroy!
end
end
end
This is the section I want to focus on:
class Recording < ApplicationRecord
belongs_to :creator, class_name: "Person", foreign_key: :person_id
belongs_to :bucket
belongs_to :parent, class_name: "Recording", optional: true
has_many :children, class_name: "Recording", foreign_key: :parent_id
delegated_type :recordable, types: %w[ Taskset Field Tasklist Task ], dependent: :destroy
end
Field
is a model that should not get delete when a Task
is deleted. I could do @task.recording.children
to see all it’s children, Yes, children
should be deleted when the parent
is deleted but in some cases, I want to be able to control that. To get around this, should I create another table with task_id
and field_id
OR record_id
and field_id
?
That new table would be called FieldTask
:
[..]
delegated_type :recordable, types: %w[ Taskset FieldTask Tasklist Task ], dependent: :destroy
How would you guys approach this?
Thanks