У меня есть модель Profile
, у которой есть вложение image
.
class Profile < ApplicationRecord
belongs_to :user, dependent: :destroy
has_one_attached :image
validates :image,
content_type: [:gif, :png, :jpg, :jpeg],
size: { less_than: 2.megabytes , message: 'must be less than 2MB in size' }
after_initialize :set_default_image
has_many :gallery_items, dependent: :destroy
accepts_nested_attributes_for :gallery_items, allow_destroy: true
validates :name, :short_description, :slug, presence: true
#...
В дополнение к проверке изображения (я использую камень проверки активной памяти ), Profile
проверяет наличие name
, short_description
и slug
.
С момента реализации этого у меня появилось новое требование в представлении. Теперь я хочу разрешить пользователю отправлять изображение отдельно от других атрибутов.
Я не хочу изменять базовую модель. Поэтому я хочу представить отдельный контроллер и класс для обработки формы только для представления изображения.
Я пробовал два способа.
Во-первых, у меня был простой класс чтобы справиться с этим:
class ProfileImageFormSubmission
def initialize(record, params)
@params = params
@record = record
end
def save
record.update_attribute(:image, image_param)
end
private
attr_accessor :params, :record
def image_param
params.fetch(record_param).require(:image)
end
def record_param
record.class.name.underscore.to_sym
end
end
Это будет вызываться в моем контроллере так:
class ProfileImagesController < ApplicationController
before_action :require_login
def update
@profile = Profile.find_by(user_id: current_user.id)
if ProfileImageFormSubmission.new(@profile, params).save
#...
Проблема в том, что изображение не проверено и поэтому прикреплено к профиль не смотря ни на что. (Я использовал #update_attribute
, потому что хотел пропустить проверки других атрибутов - не имеет смысла отображать ошибку для столбца имени, когда поле не представлено пользователю.)
Я также попытался решить проблему, выполнив проверки вне модели. Но здесь я изо всех сил пытаюсь понять, как интегрировать ActiveStorage
с простым старым Ruby объектом.
class ProfileImageFormSubmission
include ActiveModel::Model
include ActiveStorage
include ActiveStorageValidations
attr_accessor :record, :params
has_one_attached :image
validates :image,
content_type: [:gif, :png, :jpg, :jpeg],
size: { less_than: 2.megabytes , message: 'must be less than 2MB in size' }
def initialize(record, params)
@params = params
@record = record
end
def save
binding.pry
record.update_attribute(:image, image_param)
if record.invalid?
record.restore_attributes
return false
end
end
# This model is not backed by a table
def persisted?
false
end
private
def image_param
params.fetch(record_name).require(:image)
end
def object_name
record.class.name.underscore.to_sym
end
end
Я даже не могу создать экземпляр вышеупомянутого класса, поскольку он завершается ошибкой со следующей ошибкой:
NoMethodError (undefined method `has_one_attached' for ProfileImageFormSubmission:Class):
Каков наилучший способ отдельной проверки активного элемента хранения?
Можно ли запускать проверки для одного столбца без запуска других ошибок проверки?
Можно ли вообще использовать активные элементы хранения вне модели ApplicationRecord
?