In this example I have three models that I want to add an attachment too: Patient, Prescriber, Order. Each attachment requires the same attributes and instead of adding a new attachment column on each model I am electing to create a new model called "AttachmentObject" and make it polymorphic. I am using the paperclip gem with S3 for attachment upload.
class AddAttachmentPolyObject < ActiveRecord::Migration
def change
create_table :attachment_objects do |t|
t.string :title, null: false
t.references :attachable, polymorphic: true, index: true, null: false
t.attachment :attachment, null: false
t.timestamps
end
end
end
class AttachmentObject < ActiveRecord::Base belongs_to :attachable, polymorphic: true validates :title, :attachable_id, :attachable_type, presence: true end
then for my relationships to my "attachable" models (Patient, Prescriber, Order).
class Patient < ActiveRecord::Base has_many :attachment_objects, as: :attachable end
class Prescriber < ActiveRecord::Base has_many :attachment_objects, as: :attachable end
class Order < ActiveRecord::Base has_many :attachment_objects, as: :attachable end
It is not necessary to name your "has_many" relationship with a name that uses "able" as a suffix, but you will see that it is a popular amongst rails devs and you should use it as a convention when possible. Now comes the fun parts. With my AttachmentObject I can now use rails helpers to find its related attachable parent. Active Record does this by looking up the 'attachable_type' (which points to either Patient, Prescriber, or Order table) and 'attachable_id' which points to a row on the table. for example:
#explicitly order = Order.create( valid_attributes ) order_attachment = AttachmentObject.create(title: "phish", attachable_type: "order", attachable_id: order.id) #or implicitly order_attachment = AttachmentObject.create(title: "phish", attachable: order)I can then do
phish = AttachmentObject.find_by_title("phish")
phish.attachable #returns the related order_attachment
No comments:
Post a Comment