Search code examples
ruby-on-railsevalrails-activestorage

What's the best way to get options Active Storage variant from db?


I need to get a options ( for example, resize_to_limit: [300, 222], kuwahara: '3%' ) of variant Active Storage (Ruby on Rails 6.1) from the db. My decision:

app/admin/slideshow.rb

form do |f|
  f.inputs 'Slideshow' do
  f.input :name
  f.input :options,
          input_html: { value: f.object.options || "{ resize_to_limit: [300, 222], kuwahara: '3%' }" },
          label: 'Options. For example: { resize_to_limit: [300, 222], monochrome: true }'
  f.input :images, as: :file, input_html: { multiple: true }
  end
  f.actions
end

app/controllers/slideshow_controllers.rb

  def options
   @options = proc {
   $SAFE = 1
   eval(Slideshow.take.options) if slideshow
}.call
  end

  def slideshow
   Slideshow.published.take
  end

index.html.erb

<% if slideshow_present? %>
    <% @slideshow.images.each do |x| %>
        <a href="<%= path_to_file(x) %>" data-lightbox="photo" class="col-sm-4">
        <%= image_tag x.variant(@options),
                :class => "img-fluid" %>
        </a>
    <% end %>
<% end %>

app/helpers/slideshows_helper.rb

  def path_to_file(x)
   Rails.application.routes.url_helpers.rails_blob_path(x, only_path: true)
  end

But I think using eval is not the best way to go. Perhaps you can recommend the best solution for me?

P.S. Is it advisable to use Ruby safe levels?


Solution

  • It's very simple...

    app/admin/slideshow.rb

      form do |f|
        f.inputs 'Slideshow' do
          f.input :name
          f.input :options,
                  input_html: { value: f.object.options || '{ "resize_to_limit": [300, 222], "kuwahara": "3%", "quality": 15 }' },
                  label: 'Options. For example: { "resize_to_limit": [300, 222], "monochrome": true }'
          f.input :images, as: :file, input_html: { multiple: true }
        end
        f.actions
      end
    

    app/controllers/slideshow_controllers.rb

      def options
        #     @options = proc {
        #       $SAFE = 1
        #       eval(Slideshow.take.options) if slideshow
        #     }.call
        @options = JSON.parse(Slideshow.take.options) if slideshow
      end
    

    For example