ActiveStorage

 ActiveStorage

7a0e72a6f55811246bb5d9a946fd2e49?s=128

Radoslav Stankov

March 13, 2018
Tweet

Transcript

  1. ActiveStorage Radoslav Stankov 13/03/2018

  2. Radoslav Stankov @rstankov http://rstankov.com http://github.com/rstankov

  3. None
  4. 
 http://react-not-a-conf.com
 28th April

  5. None
  6. 
 http://edgeguides.rubyonrails.org/active_storage_overview.html


  7. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true end
  8. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true end
  9. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true end !
  10. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true end https://rubygems.org/gems/annotate
  11. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true end
  12. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true has_one_attached :photo end
  13. speaker.photo.attach(params[:photo])

  14. speaker.photo.nil?
 speaker.photo.present? speaker.photo.attached?

  15. speaker.photo.purge speaker.photo.purge_later

  16. None
  17. # == Schema Information # # Table name: speakers #

    # id :integer not null, primary # name :string(255) not null # bio :text # created_at :datetime # updated_at :datetime # class Speaker < ApplicationRecord validates :name, presence: true has_one_attached :photo end
  18. run rails active_storage:install run rails db:migrate

  19. create_table 'active_storage_attachments' do |t| t.string 'name', null: false t.string 'record_type',

    null: false t.bigint 'record_id', null: false t.bigint 'blob_id', null: false t.datetime 'created_at', null: false end create_table 'active_storage_blobs' do |t| t.string 'key', null: false t.string 'filename', null: false t.string 'content_type' t.text 'metadata' t.bigint 'byte_size', null: false t.string 'checksum', null: false t.datetime 'created_at', null: false end
  20. speaker.photo.metadata { 'identified' => true, 'width' => 80, 'height' =>

    80, 'analyzed' => true }
  21. speaker.photo.url #=> NoMethodError: undefined method `url' for #<ActiveStorage::Attached::One:0x007>

  22. speaker.photo.service_url

  23. image_tag speaker.photo url_for speaker.photo link_to 'download', speaker.photo

  24. <% Speaker.all do |speaker| %> <%= image_tag speaker.photo %> <%

    end %>
  25. ArgumentError in Admin::Speakers#index Showing /Users/rstankov/Projects/ConferenceBox/app/views/admin/speakers/index.html.slim where line #18 raised:

  26. ArgumentError in Admin::Speakers#index Showing /Users/rstankov/Projects/ConferenceBox/app/views/admin/speakers/index.html.slim where line #18 raised: "

  27. <% Speaker.all do |speaker| %> <%= image_tag speaker.photo if speaker.photo.attached?

    %> <% end %>
  28. ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.8ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE

    "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 35], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.4ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 30], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.6ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 40], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Blob Load (1.3ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", 16], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.0ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 23], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 18], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (2.0ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 49], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (2.0ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 7], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 21], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 11], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 10], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.4ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 50], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.0ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 52], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.2ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 17], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]] ↳ app/views/admin/speakers/index.html.slim:17 ActiveStorage::Attachment Load (1.8ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 38], ["record_type", "Speaker"], ["name", "photo"], ["LIMIT", 1]]
  29. None
  30. <% Speaker.with_attached_photo.all do |speaker| %> <%= image_tag speaker.photo if speaker.photo.attached?

    %> <% end %>
  31. None
  32. None
  33. None
  34. image_tag image.variant(resize: '100x100')

  35. ActiveStorage BlobsController ActiveStorage DiskController

  36. ActiveStorage BlobsController AWS

  37. image_tag image.variant(resize: '100x100')

  38. image_tag image.variant(resize: '100x100').service_url

  39. None
  40. speaker.photo.variant(resize:'100x100').processed.service_url

  41. None
  42. 
 http://imagemagick.org/script/index.php


  43. 
 https://www.imagemagick.org/script/command-line-options.php


  44. def speaker_photo(speaker, size:) speaker.photo.variant( resize: "#{size}x#{size}^", gravity: 'center', crop: "#{size}x#{size}+0+0"

    ) end
  45. module HasVariants def has_one_attached_with_variants(attribute_name, variants = {}) has_one_attached attribute_name define_method

    "#{attribute_name}_variant" do |variant_name| attachment = public_send(attribute_name) return unless attachment.attached? variant_options = variants.fetch(variant_name) do raise "UnknownVariant '#{variant_name}', not in #{variants.keys.join})" end attachment.variant(*variant_options) end end end #
  46. class Speaker < ApplicationRecord extend HasVariants has_one_attached_with_variants :photo, { small:

    { resize: '100x100' }, medium: { resize: '200x200' } # ... } end speaker.photo_vartiant(:small) #
  47. None
  48. None
  49. $ Disk Service % AWS Service & Azure Service '

    Google Cloud Service ( Mirror Service Services
  50. <%= form.file_field :photos, multiple: true %> 
 http://edgeguides.rubyonrails.org/active_storage_overview.html#has-many-attached


  51. image_tag talk.video.preview(resize: '100x100') image_tag talk.slides.preview(resize: '100x100') 
 http://edgeguides.rubyonrails.org/active_storage_overview.html#previewing-files


  52. 
 http://edgeguides.rubyonrails.org/active_storage_overview.html#direct-uploads
 Form Rails AWS <%= form.file_field :photos %>

  53. 
 http://edgeguides.rubyonrails.org/active_storage_overview.html#direct-uploads
 Form AWS <%= form.file_field :photos, direct_upload: true %>

  54. None
  55. None
  56. Thanks )

  57. https://speakerdeck.com/rstankov/activestorage