Rails 5.2 Active Storage Add Custom Attributes

Rails 5.2 Active Storage add custom attributes

If you need to store additional data with each image and perform queries based on that data, I’d recommend extracting an Image model that wraps an attached file:

# app/models/project.rb
class Project < ApplicationRecord
has_many :images, dependent: :destroy
end
# app/models/image.rb
class Image < ApplicationRecord
belongs_to :project

has_one_attached :file
delegate_missing_to :file

scope :positioned, -> { order(position: :asc) }
end
<%# app/views/projects/show.html.erb %>
<% @project.images.positioned.each do |image| %>
<%= image_tag image %>
<% end %>

Note that the example view above causes 2N+1 queries for a project with N images (one query for the project’s images, another for each image’s ActiveStorage::Attachment record, and one more for each attached ActiveStorage::Blob). I deliberately avoided optimizing the number of queries for clarity’s sake.

Active Storage - Adding File Description / Text - Ruby on Rails 5.2

You should create a new model to wrap each attached file. That model would then have the ActiveStorage attachment defined on it, as well as whatever other attributes you need to capture. Ex:

class Attachment < ApplicationRecord
has_one_attached :file
end

Rails then treats file kind of like an attribute for each Attachment. You can define your other attributes (e.g. upload_name, etc.) on the Attachment model. Based on your screenshot, it looks like maybe a Quotation has many attached files, so you'd do something like:

class Quotation < ApplicationRecord
has_many :attachments
end

Rails 5.2 Active Storage with Cocoon forms

You should remove the apple_images from the farmer_params (because it is not a known attribute of Apple). But removing that will make sure the images are not saved. This is however, how it is intended to work (a bit weird imho).

If you check the documentation they explicitly ignore the images attribute and set it separately:

message = Message.create! params.require(:message).permit(:title, :content)
message.images.attach(params[:message][:images])

I am not entirely sure how you should solve this in a nested form setting. You could iterate over all apples in the params and try to set the apple_images but that seems very error-prone (how do you match a new apple without id to the one that is saved?).

You could try adding a method as follows (and keep the apple_images in the permitted params):

def apple_images=(images)
self.apple_images.attach(images)
end

But not sure if that works before the apple is saved.

Rails Active Storage: How to create named variants that are cropped by user-supplied coordinates

This was added to Rails 7 (https://github.com/rails/rails/pull/39135):

class User < ActiveRecord::Base
has_one_attached :avatar, variants: {
thumb: { resize: "100x100" },
medium: { resize: "300x300", monochrome: true }
}
end

class Gallery < ActiveRecord::Base
has_many_attached :photos, variants: {
thumb: { resize: "100x100" },
medium: { resize: "300x300", monochrome: true }
}
end

<%= image_tag user.avatar.variant(:thumb) %>

Rails 5.2 + Trix + ActiveStorage

Active Storage has direct upload js, you need just add:

//= require activestorage

to your application.js, and then create trix-attachment-add event listener:

document.addEventListener('trix-attachment-add', function (event) {
var file = event.attachment.file;
if (file) {
var upload = new window.ActiveStorage.DirectUpload(file,'/rails/active_storage/direct_uploads', window);
upload.create((error, attributes) => {
if (error) {
return false;
} else {
return event.attachment.setAttributes({
url: `/rails/active_storage/blobs/${attributes.signed_id}/${attributes.filename}`,
href: `/rails/active_storage/blobs/${attributes.signed_id}/${attributes.filename}`,
});
}
});
}
});

Hope this helps you!



Related Topics



Leave a reply



Submit