Lubię pracować z Szyny ponieważ mogę łatwo i szybko stworzyć aplikację, która działa i pokazać ją światu lub tylko moim znajomym. Istnieją jednak rodzaje aplikacji, które nie potrzebują tak dużego frameworka jak Szyny i wszystkie jego funkcje.

Może się zdarzyć, że nasza aplikacja potrzebuje tylko M (Model) z całego wzorca MVC Model-Kontroler. Czy warto rozpocząć projekt w Szyny jeśli wiemy, że część V-C (View-Controller) nie będzie potrzebna?

Dobrze wiedzieć, że Aktywny rekord Active Model, Action Pack i Action View, które są odpowiedzialne za MVC, mogą być używane niezależnie poza nim. Szyny. This allows us to create a simple Ruby aplikacja który ma połączenie z bazą danych i opracować go bez zbędnego kod i biblioteki, które otrzymalibyśmy w pakiecie, uruchamiając polecenie rails new.

Opisałem krok po kroku, jak to osiągnąć, a cały kod można znaleźć na GitHub. Link znajduje się na dole tego artykułu. 

Struktura

Aby rozpocząć nasz projekt, nie potrzebujemy wiele. Zacznijmy od utworzenia pliku Gemfile gdzie dodajemy klejnoty, których potrzebujemy do pracy nad aplikacją, wraz z wersją Ruby będziemy używać.

 cat Gemfile

# frozen_string_literal: true

źródło 'https://rubygems.org'

ruby '2.7.2'

Opcjonalny README.md plik ma na celu opisanie, jak działa nasza aplikacja i jak kontynuować nad nią pracę, zarówno dla nas samych, jak i innych programistów, którzy będą chcieli rozwijać projekt z nami w przyszłości.

cat README.md

Aplikacja #

DO ZROBIENIA: Usuń ten i powyższy tekst i opisz swoją aplikację

aplikacja katalog z application.rb który będzie odpowiedzialny za konfigurację i ładowanie bibliotek i plików, które będziemy dodawać do naszej aplikacji. Pamiętaj, aby uruchomić instalacja pakietu aby wygenerować Gemfile.lock. Struktura naszej aplikacji na tym etapie powinna wyglądać następująco:

 drzewo
 .
 ├── Gemfile
 ├── Gemfile.lock
 ├── README.md
 └── app
     └── application.rb

Baza danych

Mając tak przygotowaną strukturę, możemy zastanowić się, który silnik bazy danych wybrać i skonfigurować. Na potrzeby tego artykułu wybrałem PostgresQL, z którym mam największe doświadczenie. Może to być również MySQL lub SQlite3, lub jakikolwiek inny silnik pracujący z Aktywny rekord. Przy wyborze technologii dobrze jest kierować się celem aplikacji, do czego będzie wykorzystywana i jakie będzie jej przeznaczenie. 

Do szybkiej i prostej konfiguracji bazy danych użyłem dockera i docker-compose. Nie chcę rozwodzić się nad konfiguracją tych narzędzi, ich zaletami i wadami, ale jeśli nigdy wcześniej nie korzystałeś z dockera, to odsyłam Cię do oficjalnej dokumentacji dla Docker i Docker Compose więcej informacji.

# docker-compose.yml

version: '3.7'
usługi:
  postgresql:
    image: postgres:12.0-alpine
    porty:
- 5432:5432
    środowisko:
- PGDATA=/postgresql
- POSTGRESPASSWORD=postgres
- POSTGRESUSER=postgres
    wolumeny:
- db-volume:/postgresql
volumes:
  db-volume:

Będziemy również musieli dodać do naszego Gemfile

 gem 'pg'

i do naszego application.rb plik

# app/application.rb

require 'pg'

moduł Application

  class Error < StandardError; end

# Twój kod idzie tutaj...

end

Samodzielne migracje, Rake

Następnym krokiem w konfiguracji naszej aplikacji jest dodanie pliku standalone_migrations i grabie gems, co pozwoli nam zarządzać migracjami tak jak w Railsach i uzyskać dostęp do poleceń rake db:. 

  1. Aktualizacja Gemfile z niezbędnymi klejnotami i wykonaj instalacja pakietu
Klejnot # używany w aplikacjach innych niż rails i ruby

gem 'standalone_migrations'

# standalone_migrations wymaga rake, aby móc tworzyć migracje i uruchamiać je, tak jak w Railsach.

gem 'rake'

# Gem potrzebny do załadowania zmiennych środowiskowych

gem 'dotenv'
  1. Dodajmy Rakefile do naszego projektu w katalogu głównym, gdzie będziemy ładować dotenv i standalone_migrations które dodaliśmy wcześniej 
# frozen_string_literal: true

require 'dotenv'

Dotenv.load

require 'standalone_migrations'

StandaloneMigrations::Tasks.load_tasks

Z Rakefile skonfigurowany w ten sposób, możemy sprawdzić, czy nasz grabie działa przy użyciu rake -T która powinna zwrócić listę komend dostępnych w naszej aplikacji.

aplikacja ruby
  1. Przed rake db:create, nadal musimy mieć plik konfiguracyjny w naszym projekcie, aby połączyć się z instancją Postgres. Aby to zrobić, musimy utworzyć katalog db wraz z plikiem konfiguracyjnym config.yml który powinien wyglądać jak poniżej:
# db/config.yml

default: &default

  adapter: postgresql

  kodowanie: unicode

  pool: 

  database: 

  nazwa użytkownika: 

  hasło: 

  host: 

  port: 

development:

  <<: *default

test:

  <<: *default

staging:

  <<: *default

produkcja:

  <<: *default

Jak widać, użyłem zmiennych środowiskowych do skonfigurowania połączenia z naszym Postgresem, gdzie będziemy przechowywać wrażliwe dane, które nie powinny znajdować się w repozytorium. W tym celu użyłem wcześniej dodanej zmiennej gem dotenvktóry został również dodany w Rakefile wraz z standalone_migrations. Jeśli używamy Git do zarządzania kontrolą wersji naszej aplikacji, pamiętajmy o dodaniu pliku .gitignore w którym wyłączymy możliwość śledzenia pliku .env z naszego projektu.

 # .gitignore
.env*
!.env.example

i dodać.env zawierający poprawnie skonfigurowany plik ENV

# .env

DATABASE_NAME="development"

DATABASE_USER="postgres"

DATABASE_PASSWORD="postgres"

DATABASE_HOST="localhost"

DATABASE_PORT="5432"
  1. Na tym etapie powinniśmy być w stanie uruchomić rake db:create które utworzy bazę danych

    Aplikacja internetowa Ruby

  2. Spróbujmy dodać nową migrację poprzez rake db:new_migration name=gdzie tworzymy stanowiska tabela z :title kolumna

    Aplikacja internetowa Rails

# frozen_string_literal: true

class CreatePosts < ActiveRecord::Migration[6.0]

  def change

    create_table :posts do |t|

      t.string :title

    end

  end

koniec
Aplikacja internetowa Ruby on Rails

Powinieneś zauważyć, że db/migrate został automatycznie dodany i schema.rb została utworzona po udanej migracji. Obecnie struktura naszego projektu wygląda następująco:

 drzewo
.
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── .gitignore
├── .env.example
├── app
│ └── application.rb
├── db
│ ├── config.yml
│ ├── migrate
│ └── 20210504135128_create_posts.rb
│ └── schema.rb
└── docker-compose.yml

Aktywny rekord

Ostatnim, ale nie mniej ważnym, krokiem w tworzeniu naszej aplikacji jest dodanie activerecord i jego konfigurację. W tym celu będziemy musieli zaktualizować nasz plik Gemfile o 3 dodatkowe klejnoty:

gem 'activerecord'
gem 'erb'
gem 'yaml'

Dlaczego dodajemy erb i ymal wyjaśniono poniżej w komentarzach. Całość active_record konfiguracja będzie znajdować się w app/application.rb plik.

Przejdźmy przez to, co się tutaj dzieje, jeden po drugim:

# frozen_string_literal: true

# Jeśli chcemy mieć możliwość uruchamiania aplikacji w różnych środowiskach,
# np. testowym lub produkcyjnym, dobrze jest ustawić wartość ENVIRONMENT
# na początku, która jest pobierana ze zmiennej środowiskowej
# lub domyślnie `development`.

ENV['ENVIRONMENT'] ||= 'development'

# Aby użyć dodanych klejnotów, musimy je załadować za pomocą metody Kernel#require,
#, która ładuje plik lub bibliotekę przekazaną jako parametr

require 'pg'
require 'active_record'
require 'dotenv'
require 'yaml'
require 'erb'

# Domyślnie Dotenv.load do ładowania zmiennych środowiskowych sięga do pliku
# do pliku `.env`, więc jeśli chcemy korzystać z innych środowisk, warto
# rozszerzyć to do poniższej metody, która najpierw dla zestawu rozwojowego
# szuka pliku kończącego się na `.env.development.local`,
# następnie `.env.development` i na końcu `.env`.

Dotenv.load(".env.#{ENV.fetch('ENVIRONMENT')}.local", ".env.#{ENV.fetch('ENVIRONMENT')}", ".env")

# Metoda potrzebna do załadowania ustawień bazy danych
def db_configuration
  # Poniższa metoda zwraca ścieżkę do pliku z naszą konfiguracją
  db_configuration_file_path = File.join(File.expand_path('.', __dir__), 'db', 'config.yml')

  # Mając ścieżkę do pliku, możemy odczytać jego wartości. Ponieważ plik config.yml
  # zawiera zmienne środowiskowe i, jak być może zauważyłeś,
  # składnię erb , musimy również użyć klejnotu erb. Bez tego,
  # wartości zmiennych nie zostaną poprawnie odczytane, a activerecord
  # nie będzie w stanie połączyć się z postgres.Następująca metoda zwróci
  # konfigurację jako ciąg znaków

  db_configuration_result = ERB.new(File.read(db_configuration_file_path)).result

  # Korzystając z wcześniej dodanego klejnotu `yaml`, możemy bezpiecznie załadować naszą konfigurację

  YAML.safe_load(db_configuration_result, aliases: true)
end

# Na koniec musimy utworzyć połączenie między activerecord i postgres
# używając metody `establish_connection`
ActiveRecord::Base.establish_connection(db_configuration[ENV['ENVIRONMENT']])

moduł Application
  class Error < StandardError; end
  # Twój kod znajduje się tutaj...
end

Mamy już konfiguracje, więc możemy dodać model Post w naszej aplikacji rubin aplikacja. 

`├── app`

`│ └── modele`

`│ └── post.rb`
app/models/post.rb
# frozen_string_literal: true

class Post < ActiveRecord::Base; end

i pamiętaj, aby załadować plik w application.rb

require 'app/models/post'

Należy również pamiętać o dodaniu require 'app/runner' do app/application.rb

Jeśli chcemy dodać nowe pliki do naszej aplikacji, usługi, więcej modeli, musimy załadować je do aplikacji application.rb.

PODSUMOWANIE

Obecnie nasza aplikacja ruby jest gotowa do działania. Skonfigurowaliśmy:

Jak widać, nie zawsze konieczne jest używanie szyny nowe. W ten sposób unikamy niepotrzebnego kodu w naszej aplikacji, który nie jest używany. Mamy większą kontrolę nad rozwojem naszej aplikacji. Z czasem możemy dodawać kolejne biblioteki i logikę biznesową. Tak skonfigurowaną aplikację możemy wykorzystać do stworzenia crawlera lub scrapera, łączenia się z zewnętrznym API, z którego będziemy pobierać informacje i przechowywać we własnej bazie danych lub wczytywać pliki i wyciągać z nich interesujące informacje. Życzę powodzenia w dalszym rozwoju własnych aplikacji!

BONUS

Nasza aplikacja również musi zostać w jakiś sposób uruchomiona. Możemy to zrobić na kilka sposobów, na przykład z terminala. Możemy utworzyć plik exe/app który załaduje logikę naszej aplikacji z pliku 'app/application' i uruchomić naszą aplikację poprzez Biegacz dodana w katalogu aplikacji.

#!/usr/bin/env ruby
# frozen_string_literal: true

require 'bundler/setup'

$LOAD_PATH.unshift File.expand_path('.', __dir__)
require 'app/application'

Runner.start
# frozen_string_literal: true

class Runner
  def self.start
    puts 'Start'
  end
end
tworzenie aplikacji ruby

Należy również pamiętać o dodaniu require 'app/runner' do app/application.rb

Kod można znaleźć na GitHub:

https://github.com/dwatek/simplerubinaplikacja

Czytaj więcej

GraphQL Ruby. Co z wydajnością?

Szyny i inne środki transportu

Rails Development z TMUX, Vim, Fzf + Ripgrep

pl_PLPolish