Pobieranie danych z tabeli

Witam.

Mam napisana aplikację która wykonuje kilka operacji na danych. Dane te są teraz wpisywane z palca w tej aplikacji z innej aplikacji, która tez jest oparta na bazie danych.
Chcę te dane pobierać automatycznie i wrzucać je do odpowiednich tabel.

Gdzie powinien znaleźć się kod za to odpowiedzialny, w kontrolerze czy widoku.
Chce zrobić funkcję get_data(), która będzie odpalana automatycznie po zalogowaniu do aplikacji, a i w razie potrzeby aby było ją można odpalić ręcznie.

Czy potrzebuję tworzyć model i kontroler do tego czy wystarczy kontroler.
Dodam że pobrane dane z innej aplikacji, będą troszkę zmieniane zanim trafią do mojej aplikacji.

Pozdrawiam
Sebastian

Na pewno nie w widoku.
Czy tworzyć model… hmm z Twojego opisu nie wynika jakie to są właściwie dane i ile tego jest - jakieś modele pewnie w tej operacji powstaną.
Wygląda mi to na proces na tyle złożony, że warto go wydzielić do jakiegoś pomocniczego modułu/metody w lib i wtedy wywoływać przy zalogowaniu i w samodzielnej akcji.

Chcesz dokonać konwersji danych, pod własna strukturę bazy danych - to zrozumiałem z Twojego postu.

Moim zdaniem najlepiej oprzeć się na modelach, tj.:

  1. stworzyć modele/tabele w aplikacji railsowej odpowiadające strukturze, jaką chcesz uzyskać
  2. stworzyć modele, które będą podpięte do bazy danych, z której chcesz importować dane i będą mapowały rekorty z tabel na obiekty (AFAIR w ramach jednej aplikacji railsowej możesz podpiąć się do wielu baz danych, trzeba przy definicji modelu pomieszać)
  3. w modelu docelowym stworzyć metodę create_with! albo import, nazwij jak chcesz. metoda ta bierze do “łapy” stary model i go konwertuje do nowego i zapisuje w bazie danych.
  4. W modelu “docelowym” stwórz metodę, która będzie pobierała wszystkie dane ze “starej” bazy danych (może pobierać np. parametry do połączenia)
  5. jeżeli chcesz pozwolić użytkownikom Twojej aplikacji na taki import (tj. nie wykonujesz importu jednokrotnie), to stwórz kontroler, który

Pomocny może być w 5 sekund wyguglany link: http://robbyonrails.com/articles/2007/10/05/multiple-database-connections-in-ruby-on-rails

nie wiem, czy wciąż aktualne dla obecnych wersji Rails

Bardzo uproszczony przykład:

[code=ruby]class Legacy::Customer < ActiveRecord::Base

tutaj magia jakaś do podłaczenia się do “starej” bazy danych

zakładam, że tabela ta pola:

name: string

company: boolean

end

class Customer < ActiveRecord::Base
def self.import_legacy_customer!(customer)
if customer.is_a? Legacy::Customer
hash = {:company => customer.company?}
if customer.company?
hash[:name] = customer.name
else
hash[:first_name] = customer.name.split(’ ‘).first
hash[:last_name] = customer.name.split(’ ').last
end
self.create!(hash)
end
end

def self.import_all_legacy_customers!
Legacy::Customer.find_each(:batch_size => 100) do |legacy_customer|
self.import_legacy_customer!(legacy_customer)
end
end
end[/code]
to tylko idea, którą nalezy dopracować. Logika importowania danych, a także ODWZOROWANIE “starych” danych należą do modelu biznesowego. Kontroler może jedynie zainicjować importowanie danych, tj. pobrać jakieś parametry, uruchomić metodę w modelu. Widok jest warstwą PREZENTACJI (użytkownikowi) danych, więc nijak ma sie do przedstawionego problemu.

Dodam, że powyższy pomysł może być zastosowany również w obrębie jednej bazy danych (nawet mniej roboty)

EDIT: można też zrobić to od drugiej strony: w Legacy::Customer zrobić metody eksportujące do nowej bazy danych - pamiętaj wtedy o pisaniu np. ::Customer.create!(). Zaletą tego jest to, że logika migracji danych zostaje w modelach reprezentujących “stare” dane i może być łatwo usunięta z aplikacji, gdy nie będzie już potrzebna.

[quote=l0pez]Czy potrzebuję tworzyć model i kontroler do tego czy wystarczy kontroler.
Dodam że pobrane dane z innej aplikacji, będą troszkę zmieniane zanim trafią do mojej aplikacji.[/quote]
Jeżeli cokolwiek zajmuje więcej niż jedna czy dwie linijki, to powinieneś to gdzieś przerzucić. Nie musi to być koniecznie model, może być zwykła klasa, np. FooDataFetcher. Powinno się robić coś takiego ze względu na to, ze logikę w kontrolerach i widokach ciężko się później zmienia/refaktoryzuje. Jeżeli masz kilkanaście (albo i kilkadziesiąt) linijek w kontrolerze i nagle przychodzi klient i mówi, ze potrzebuje czegoś takiego w innym kontekście, to zakładając, że masz niewiele czasu na 99% zrobisz copypastę do innego kontrolera. Co później prowadzi tylko do dalszych problemów (włącznie z tym, że takie kontrolery ciężko się testuje, a w tym momencie masz już 2 takie miejsca).

Jeżeli kod wygląda tak:

class FooController < ActionController::Base def fetch FooDataFetcher.new(params[:some_config_data]).fetch end end
to później bardzo łatwo możesz wykorzystać ten kod w innym miejscu. Jeżeli zachowanie w innym kontolerze musi się trochę różnić, a kod w FooDataFetcher jest rozbity na małe metody, to bardzo łatwo możesz zrobić klasę dziedziczącą po FooDataFetcher, np.

[code]class BarDataFetcher < FooDataFetcher

end[/code]
i nadpisać tylko te kawałki, które się będą różnić (w zasadzie to można wtedy zrobić jedną wspólną klasę typu GenericDataFetcher, po którym będą dziedziczyły obie klasy, ale to czy opłaca się tak robić zależy od konretnej implementacji).

To takie moje 3 grosze na temat designu aplikacji.