Reverse db->schema czyli 'schema_to_scaffold' w natarciu

Witam Wszystkich serdecznie!

Od jakiegoś czasu staram się nauczyć posługiwania RoR i jak to wyczytałem w jakimś poradniku, to po zapoznaniu się z podstawami, najlepiej zacząć robić jakiś projekt.

jakieś drobne i banalne rzeczy przebrnąłem i rzuciłem się na głęboką wodę - postanowiłem przenieś pewien produkcyjny system.
Stan aktualny:
Baza Firebird, klient napisany C++ pod Windę, aplikacja zainstalowana na serwerze Windows 2008 w chmurze i udostępniana poprzez RDP (Terminal Serwer).

Opłaty za licencje klientów terminalowach małe nie są, ja chcę opanować Ruby on Rails więc… do dzieła :smile:

Środowisko developerskie:
Ubuntu 12.04,
Ruby version 2.1.2-p95 (i686-linux)
RubyGems version 2.2.2
Rack version 1.5
Rails version 4.1.1
JavaScript Runtime Node.js (V8)
Active Record version 4.1.1
Action Pack version 4.1.1
Action View version 4.1.1
Action Mailer version 4.1.1
Active Support version 4.1.1

Zgodnie ze znalezionymi informacjami


http://webmaster-blog.pl/2013/01/rails-scaffold-jak-wygenerowac-crud-scaffold-na-podstawie-istniejacej-bazy-mysql/

wstawiłem do pliku Gemfile
gem ‘activerecord-fb-adapter’
gem ‘schema_to_scaffold’,

a w databses.yml
development:
adapter: fb
database: /sciezka/baza.fdb
username: SYSDBA
password: moje_haslo
#password: masterkey
host: localhost
encoding: UTF-8
create: true

i zgodnie z instrukcjami, wykonałem.
bundle install
rake db:schema:dump
czego efektem było utworzenie “schema.rb”, które chciałem wykorzystać jako bazę dla instrukcji:
scaffold -p /ścieżkadoaplikacji/nazwaaplikacji/db/schema.rb

I tutaj nastąpiła konsternacja. Wygenerowane modele tablic są niepełne.
Są tam co prawda instrukcje “create table…” i nawet “add_index …” ale na tym precyzja tego reverse engineering się kończy. A gdzie instrukcje has_many, belongs_to ? Przecież w mojej bazie mam kilkadziesiąt tabel i relacje między nimi! :frowning:

Moje pytanie jest następujące:
Czy to wina sterownika do Firebirda?
Czy znacie może jakieś inne narzędzie/sposób, który pozwoli precyzyjniej przenieś schemat bazy do pliku schema.rb?

Edit:
W zasadzie, to tytuł jest nieadekwatny, gdyż scaffold -p /ścieżkadoaplikacji/nazwaaplikacji/db/schema.rb nawet nie wykonałem widząc taki schemat.

W rails nie wykorzystuje się relacji zapisanych w bazie danych, zamiast tego relacje zapisuje się w modelach (w twoim przypadku klasach dziedziczonych po ActiveRecord::Base)

Czyli to nie “rake db:schema:dump” (które tworzy schema.rb), a dopiero “scaffold -p /ścieżkadoaplikacji/nazwaaplikacji/db/schema.rb” zbuduje modelei i wpisy zależności typu has_many?

Przecież takie modele będą tworzone na podstawie właśnie schematu, zatem skoro w schemacie nie ma info o takich zależnościach między tabelami, to skąd scaffold “będzie wiedział”, gdzie dodać “has_many”?

Ponawiam zatem pytanie, czy mechanizm odwzorowania istniejącej bazy na schemat i modele RoR jest zwyczajnie taki przaśny i trzeba to ręcznie uzupełnić, cz też może znacie inny sposób, by precyzyjniej odzworować istniejącą bazę do schematu i modeli Ruby on Rails?

z tego co widze to schema_to_scaffold tworzy scaffold z bazy danych. A relacje to zupełnie inna rzecz, Rails po prostu nie obsługuje relacji na poziomie bazy danych a jedynie na poziomie modeli. Scaffold to utworzenie nie schemy tylko podstawowych kontrolerów i widoków w celu dodawania pozycji do bazy danych. O relacji trzeba zadbać samemu i pouzupełniać je ręcznie.

Hmm …
To co dalej? Mam zdjąć takie relacje w istniejącej bazie danych i dopisać je ręcznie do modeli RoR? :open_mouth:

Przyznam szczerze, że bardziej ufam relacjom (i ogólnie mechanizmom integralności) zdefiniowanym na poziomie bazy danych, a nie po stronie aplikacji klienckich. :frowning:

Nie musisz ich zdejmować, możesz je zduplikować w modelach, tylko musisz pilnować wtedy, żeby tu i tu były takie same relacje.

Ok, przyjdzie mi to “przełknąć” …

Czy znany jest Wam jakiś gem (lub inne narzędzie), które automatycznie generuje nie tylko schema.rb ale także modele (i wpisy has_many :D) na podstawie już istniejącej bazy danych?

Jeżeli chcesz używać kluczy obcych to polecam gema foreigner

Dzięki za podpowiedź.
Znalazłem w opisie tego gema ‘foreigner’ odnośnik do gem immigrant i to jest chyba to czego szukam. :slight_smile:

Edit:
… Ale już się przestałem cieszyć:
Po wykonaniu:
rails generate immigration AddKeys
otrzymałem odpowiedź:
“Database adapter fb not supported…” a dokładniej: “Database adapter fb not supported. Use:\nForeigner::Adapter.register ‘fb’, ‘path/to/adapter’”.
Da się coś z tym dalej zrobić?

Wracając na chwilę do samego projektu, to historia jego zmian jest długa.
Kilka lat temu były to lokalne aplikacje u klientów w biurach, więc osobne bazy danych. Teraz są to nadal osobne bazy , gdyż jestem leniwy :frowning: i nie chciało mi się zbijać ich w jedną, (chociaż ich wersje i struktury są jednakowe).

Uważacie, że łatwiej będzie napisać aplikację w ROR, gdy nadal będą to osobne bazy, a użytkownik po zalogowaniu się do xxx.xxx.xxx/moja_app (bazy wsþólnej-serwisowej) będzie następnie rozłączany i ponownie łączony, ale tym razem już ze “swoją” bazą?
Czy może nadszedł jednak ten czas, by zbić dane w jedną bazę i użytkownikom filtrować je z warunkiem “where user.id = X” ?

Ja wybrałbym Wielkanoc.

1 Like

Mam przez to rozumieć, że dywagacje, czy lepiej pracować na jednej bazie i odfiltrowywać dane ze względu na zalogowanego użytkownika, a pracować na wielu bazach, której wybór do połączenia następuje po zalogowaniu wstępnym do jakiejś bazy serwisowej, to dyskusja nad wyższością Bożego Narodzenia lub Wielkanocy?

Hmm…
Sądziłem, że stosowanie generatorów, które jednak w jakiś sposób tworzą szkielet aplikacji, determinuje pewne podejście i że pewien schemat jest jednak preferowany.
Zwróć proszę uwagę na to, że kwestia wydajności baz/bazy nie ma absolutnie znaczenia.

No cóż …
Dzięki za sugestie i wskazanie różnorodnych za i przeciw koncepcji aplikacji z wieloma bazami versus aplikacja z jedną bazą i modyfikowanie zapytań, by wybierać tylko dane określonego użytkownika.

Pozdrawiam :smile: