Search code examples
ruby-on-railsruby-on-rails-6rails-activestorage

How to skip Rails validations when using ActiveStorage "attach"


I have a model with a Logo as attachment.

When user uploads an image, the validation name and url validation should be skipped.

The validates :logo should be still validated

Is this possible, and if yes: How?

Thank you!

class MyModel < ApplicationRecord
  belongs_to :user

  has_one_attached :logo do |attachable|
    attachable.variant :thumbnail, resize_to_fit: [100, 100]
  end

  validates :logo, content_type: %w[image/png image/jpg image/jpeg]

  # following line should be skipped
  validates_presence_of :name, :url # this should be skipped when attaching an image !!!

end

# MyModelController
# That is my current controller action

  # PATCH /shops/update_logo
  def update_logo
    if logo_params[:logo].present?
      logo = logo_params[:logo]
      if logo && @current_user.my_model.logo.attach(logo)
        render json: @current_user, status: :ok
      else
        render json: @current_user.my_model.errors, status: :unprocessable_entity, error: @current_user.my_model.errors.full_messages.join(', ')
      end
    else
      render json: { error: "no image selected" }, status: :unprocessable_entity
    end
  end


Solution

  • Some hack with :on

    class MyModel < ApplicationRecord
      validates :name, :url, presence: true, on: :not_attachment
      validates :logo, content_type: %w[image/png image/jpg image/jpeg]
    end
    
    my_model.name = my_model.url = nil
    my_model.logo.attach(logo)
    my_model.valid? # => true
    
    my_model.name = my_model.url = nil
    my_model.save(context: :not_attachment)
    my_model.valid? # => false