/ február 16, 2018/ Ruby on Rails/ 0 comments

Az új Rails változatot a következő paranccsal telepíthetjük fel:

gem install rails --prerelease

A legnagyobb újdonság, amit ez a verzió hoz, az Active Storage. Most először a Rails beépítetten támogatja a fájlok feltöltését. Eddig a Paperclip vagy CarrierWave gem-eket kellett használnunk.

Fájl feltöltése

Első lépésként adjuk ki a

rails active_storage:install

parancsot, ami létrehoz egy db/migrate migrációt, ami két táblát hoz létre: active_storage_attachments és active_storage_blobs.

Először a modelben kell változtatunk:

has_one_attached :image

Aztán a controllerben engedélyezni a paramétert:

  params.require(:post).permit(:title, :content, :image)

És hozzáadni a képet valahol a kódban így:

@post.image.attach(params[:image])

vagy kirakni egy form-ra:

<%= form.label :image %>
<%= form.file_field :image %>

Megjeleníteni így tudjuk:

<% if @post.image.attached? %>
  <p>
    <strong>Image:</strong>
    <br>
    <%= image_tag @post.image %>
  </p>
<% end %>

A controllerben a

@posts = Post.all

helyett írjuk azt, hogy

@posts = Post.with_attached_image

így elkerüljük az n+1 lekérdezés problémát.

Több fájl feltöltése

Modelben:

has_many_attached :images
scope :with_eager_loaded_images, -> { eager_load(images_attachments: :blob) }

Controllerben:

  params.require(:post).permit(:title, :content, images: [])

View-ban:

<!-- app/views/posts/_form.html.erb -->
<div class="field">
  <%= form.label :images %>
  <%= form.file_field :images, multiple: true %>
</div>

<!-- app/views/posts/show.html.erb -->
<% if @post.images.attached? %>
<p>
  <strong>Images:</strong>
  <br>
  <% @post.images.each do |image| %>
    <%= image_tag(image) %>
  <% end %>
</p>
<% end %>

Fájlok törlésére a purge és a purge_later metódus áll rendelkezésre. A második az ActiveStorage::PurgeJob segítségével később töröl a háttérben.

ImageMagick

Adjuk hozzá a mini_magick gemet a Gemfile-hoz, majd használjuk:

<%= image_tag image.variant(resize: "500x500", monochrome: true) %>

Az átalakítás az első böngészőből történő lekéréskor lesz átalakítva. Ha azonnal akarjuk:

image.variant(resize: "100x100").processed.service_url

Ha használjuk az ImageMagick-et, rendelkezésünkre áll a post.image.metadatametódus is, ami visszaadja a kép szélességét, magasságát.

Fejlesztői módban a helyi gépet használja tárolónak, de élesen felhőbe is tölthetjük a képeket.

Jelszavak kezelése

config/credentials.yml.enc fájlban történik, be is tehető verziókezelőbe, a mesterkulcs (master.key) pedig a központi jelszókezelőbe. A rails credentials:edit paranccsal szerkeszthetők a kulcsok.

Egy kulcs így érhető el:

Rails.application.credentials.key_name

vagy ha többszintű:

Rails.application.credentials.dig(:section_name, :nested_key_name)

A mesterkulcs éles rendszeren a RAILS_MASTER_KEY változóval adható meg.

Felhő

Ha amazonban szeretnénk tárolni, azt így adhatjuk meg:

config.active_storage.service = :amazon

Direct upload segítségével javascript-el közvetlenül is feltölthetünk fájlokat, illetve tükrözés segítségével több felhőszolgáltatónál is tárolhatjuk fájljainkat.

Biztonság

A Mozilla által kifejlesztett CSF (Content Security Policy) segítségével biztonságosabbá tehetjük alkalmazásunkat:

# config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |p|
 # allow everything from the current hostname by default (only secured)
 p.default_src :self, :https
 # allow loading fonts and images from data-uri
 p.font_src :self, :https, :data
 # don't forget to add your cloud hostname for ActiveStorage assets
 p.img_src :self, :https, :data, "cloudfront.example.com"
 # disallow <object> tags (Good-bye Flash!)
 p.object_src :none
 # allow inline <style> (remove :unsafe_inline if you don't want it)
 p.style_src :self, :https, :unsafe_inline
  if Rails.env.development?
    p.script_src :self, :https, :unsafe_eval
    p.default_src :self, :https, :unsafe_eval
    p.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035'
  else
    p.script_src :self, :https
    p.default_src :self, :https
  end
end

Current_*

Gyakori fórumkérdés, hogy modelből hogy érhetjük el az aktuális felhasználót. Most erre is születik egy megoldás:

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :user
end

Egy bárhonnan elérhető egy példányban létező osztály:

class ApplicationController < ActionController::Base
  before_action :set_current_user

  private

  def set_current_user
    Current.user = current_user
  end
end

Használata:

# and now in your model
class Post < ApplicationRecord
  # You don't have to specify the user when creating a post,
  # the current one would be used by default
  belongs_to :user, default: -> { Current.user }
end

HTTP2

Ha a puma kiszolgálónak adunk egy –early_hints kapcsolót, akkor HTTP2 hinteket tud küldeni pl. egy h2o szerver mögül.

Bootsnap

Egy nagy monolitikus alkalmazás akár percekig is indulhat. Vagy egy rake task. A spring fölé került egy Bootsnap nevű – a Shopify által fejlesztett – Ruby és yaml fájlokat gyorsabban betöltő (2-4x) eszköz.

Forrás: https://evilmartians.com/chronicles/rails-5-2-active-storage-and-beyond

Leave a Comment