MVC to wzorzec projektowy, który dzieli obowiązki aplikacji, aby ułatwić poruszanie się po niej. Railsy podążają za tym wzorcem projektowym zgodnie z konwencją.
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. Pozwala nam to na stworzenie prostego Aplikacja Ruby 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:
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.
# 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:.
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'
Dodajmy Rakefile do naszego projektu w katalogu głównym, gdzie będziemy ładować dotenv i standalone_migrations które dodaliśmy wcześniej
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.
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:
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
Na tym etapie powinniśmy być w stanie uruchomić rake db:create które utworzy bazę danych
Spróbujmy dodać nową migrację poprzez rake db:new_migration name=gdzie tworzymy stanowiska tabela z :title kolumna
# frozen_string_literal: true
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.string :title
end
end
koniec
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:
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:
połączenie z bazą danych,
Aktywny rekord,
Samodzielne migracje z użyciem rake
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.