advanced image management
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
ActiveAdmin.register Software do
|
||||
permit_params :name, :title, :author, :desc, :story,
|
||||
:license, :platform, :status, :highlighted, :image_id,
|
||||
:license, :platform, :status, :highlighted,
|
||||
software_images_attributes: [ :id, :image_id, :is_default, :position, :_destroy ],
|
||||
external_links_attributes: [ :id, :label, :url, :_destroy ],
|
||||
releases_attributes: [ :id, :version, :html_folder_path, :cartridge_path, :source_path, :docs_folder_path, :web_playable, :_destroy ]
|
||||
|
||||
@@ -19,8 +20,9 @@ ActiveAdmin.register Software do
|
||||
end
|
||||
column :highlighted
|
||||
column(:image) do |sw|
|
||||
if sw.image && File.exist?(sw.image.file_path)
|
||||
image_tag "/api/image/#{sw.image.id}", style: "max-height:40px;max-width:80px;object-fit:contain;"
|
||||
si = sw.software_images.detect(&:is_default?) || sw.software_images.first
|
||||
if si&.image && File.exist?(si.image.file_path)
|
||||
image_tag "/api/image/#{si.image_id}", style: "max-height:40px;max-width:80px;object-fit:contain;"
|
||||
end
|
||||
end
|
||||
column :created_at
|
||||
@@ -44,13 +46,19 @@ ActiveAdmin.register Software do
|
||||
f.input :status, as: :select, collection: %w[development demo released archived]
|
||||
f.input :highlighted
|
||||
f.input :license
|
||||
f.input :image_id, as: :select, label: "Image",
|
||||
collection: Image.order(:original_filename).map { |img| [ img.original_filename, img.id ] },
|
||||
include_blank: "— no image —"
|
||||
f.input :desc, as: :text, input_html: { rows: 4 }
|
||||
f.input :story, as: :text, input_html: { rows: 8 }
|
||||
end
|
||||
|
||||
f.inputs "Images" do
|
||||
f.has_many :software_images, allow_destroy: true, new_record: true do |si|
|
||||
si.input :image_id, as: :select, label: "Image",
|
||||
collection: Image.order(:original_filename).map { |img| [img.original_filename, img.id] }
|
||||
si.input :is_default, as: :boolean
|
||||
si.input :position, as: :number, input_html: { min: 0 }
|
||||
end
|
||||
end
|
||||
|
||||
f.inputs "External Links" do
|
||||
f.has_many :external_links, allow_destroy: true, new_record: true do |el|
|
||||
el.input :label
|
||||
@@ -73,6 +81,12 @@ ActiveAdmin.register Software do
|
||||
end
|
||||
end
|
||||
|
||||
controller do
|
||||
def scoped_collection
|
||||
super.includes(:software_images)
|
||||
end
|
||||
end
|
||||
|
||||
form do |f|
|
||||
f.inputs "Details" do
|
||||
f.input :name
|
||||
@@ -82,13 +96,19 @@ ActiveAdmin.register Software do
|
||||
f.input :status, as: :select, collection: %w[development demo released archived]
|
||||
f.input :highlighted
|
||||
f.input :license
|
||||
f.input :image_id, as: :select, label: "Image",
|
||||
collection: Image.order(:original_filename).map { |img| [ img.original_filename, img.id ] },
|
||||
include_blank: "— no image —"
|
||||
f.input :desc, as: :text, input_html: { rows: 4 }
|
||||
f.input :story, as: :text, input_html: { rows: 8 }
|
||||
end
|
||||
|
||||
f.inputs "Images" do
|
||||
f.has_many :software_images, allow_destroy: true, new_record: true do |si|
|
||||
si.input :image_id, as: :select, label: "Image",
|
||||
collection: Image.order(:original_filename).map { |img| [img.original_filename, img.id] }
|
||||
si.input :is_default, as: :boolean
|
||||
si.input :position, as: :number, input_html: { min: 0 }
|
||||
end
|
||||
end
|
||||
|
||||
f.inputs "External Links" do
|
||||
f.has_many :external_links, allow_destroy: true, new_record: true do |el|
|
||||
el.input :label
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
class Image < ApplicationRecord
|
||||
UPLOAD_PATH = ENV.fetch("IMAGE_CONTAINER_PATH", "/images")
|
||||
|
||||
has_many :software_images, dependent: :restrict_with_error
|
||||
|
||||
attr_accessor :file_upload
|
||||
|
||||
before_save :process_upload, if: -> { file_upload.present? }
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
class Software < ApplicationRecord
|
||||
self.table_name = "softwares"
|
||||
|
||||
belongs_to :image, optional: true
|
||||
|
||||
has_many :software_images, foreign_key: :software_id, dependent: :destroy
|
||||
has_many :images, through: :software_images
|
||||
has_many :releases, foreign_key: :software_id
|
||||
has_many :external_links, foreign_key: :software_id
|
||||
|
||||
accepts_nested_attributes_for :software_images, allow_destroy: true
|
||||
accepts_nested_attributes_for :external_links, allow_destroy: true
|
||||
accepts_nested_attributes_for :releases, allow_destroy: true
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[author created_at desc highlighted id image_id license name platform site status story title updated_at]
|
||||
%w[author created_at desc highlighted id license name platform site status story title updated_at]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w[releases external_links image]
|
||||
%w[releases external_links software_images images]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
class SoftwareImage < ApplicationRecord
|
||||
belongs_to :software
|
||||
belongs_to :image
|
||||
|
||||
validates :image_id, uniqueness: { scope: :software_id }
|
||||
validates :position, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
|
||||
before_save :unset_other_defaults, if: -> { is_default? && is_default_changed? }
|
||||
|
||||
default_scope { order(:position) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[created_at id image_id is_default position software_id updated_at]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w[image software]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unset_other_defaults
|
||||
SoftwareImage.where(software_id: software_id, is_default: true)
|
||||
.where.not(id: id)
|
||||
.update_all(is_default: false)
|
||||
end
|
||||
end
|
||||
@@ -16,5 +16,13 @@ class SoftwareSerializer < Blueprinter::Base
|
||||
field :status
|
||||
field(:highlighted) { |sw| sw.highlighted ? true : false }
|
||||
field(:externalLinks) { |sw| ExternalLinkSerializer.render_as_hash(sw.external_links) }
|
||||
field(:imageUrl) { |sw| sw.image_id ? "/api/image/#{sw.image_id}" : nil }
|
||||
field(:imageUrl) { |sw|
|
||||
si = sw.software_images.detect(&:is_default?) || sw.software_images.first
|
||||
si ? "/api/image/#{si.image_id}" : nil
|
||||
}
|
||||
field(:images) { |sw|
|
||||
sw.software_images.map { |si|
|
||||
{ url: "/api/image/#{si.image_id}", isDefault: si.is_default?, position: si.position }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@ class SoftwareHighlightedService
|
||||
include SoftwareResponseBuilder
|
||||
|
||||
def index
|
||||
software = Software.includes(:external_links, :image)
|
||||
software = Software.includes(:external_links, :software_images)
|
||||
.where(highlighted: true)
|
||||
.order(id: :desc)
|
||||
.first
|
||||
|
||||
@@ -2,7 +2,7 @@ class SoftwareService
|
||||
include SoftwareResponseBuilder
|
||||
|
||||
def index
|
||||
softwares = Software.includes(:releases, :external_links, :image).all
|
||||
softwares = Software.includes(:releases, :external_links, :software_images).all
|
||||
{ softwares: softwares.map { |sw| build_response(sw, sw.releases.to_a) } }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user