Witam.
Tworzę pierwszy projekt w RoR i mam pewien problem z relacjami pomiędzy tabelami w AR. Mam 2 tabele: user i task. W tabeli task jest klucz obcy responsible_id (dla pola user.id) .
Tak więc w modelu task mam:
belongs_to :user, :foreign_key => “responsible_id”
Pobieranie rekordów z połączonych tabel task i user wykonuje poprzez (btw czy muszę podawać :joins?):
Task.find(:all, :joins => :user, :select => “task.*, user.name AS user”)
Wszystko działa dopóki nie będę chciał dodać nowego użytkownika do tabeli user bo wtedy pojawia się błąd, że nie istnieje task o id usera którego chce dodać. Czy tak jakby relacja działa w drugą stronę.
Co robię źle bo mam wrażenie że czegoś nie rozumiem w związku z relacjami?
Czy jeśli użyję belongs_to to muszę dodatkowo definiować has_many dla tabeli nadrzędnej (czy oba wpisy nie powodują tego samego)?
has_many :tasks, :foreign_key => "responsible_id"
Jeśli chce użyć aliasów w tabli dołączanej to muszę chyba użyć :select bo :include dołączy mi po prostu wszystkie kolumny z drugiej tabeli:
tasks = Task.find(:all, :include => :user)
Przepraszam za te pewnie lamerskie pytania ale studiuje od kilku dni dokumentację i liczne przykłady w necie ale jakoś nie mogę znaleźć jednoznacznej odp. na swoje pytania.
Coś mi świta w głowie, że railsy (tylko nie pamiętam która wersja) w takim wypadku ostrzega żeby dodać explicite nazwę klasy, bo w nowszych wersjach sposób jej określania może ulec zmianie. Lepiej moim zdaniem podać nazwę klasy, ale jeśli działa bez to też ok.
Musisz i nie musisz. Jeśli nie chcesz by jakaś klasa wiedziała o relacji to nie dodajesz wpisu. Dodanie asocjacji z jednej strony nie powoduje automatycznie utworzenie z drugiej.
Po co Ci aliasy? Jeśli aliasujesz jakąś kolumnę to wystarczy, że zrobisz tak jak ja proponowałem i dodatkowo zdefiniujesz sobie taką metodę jak nazwa aliasu, która będzie zwracać wartość tej aliasowanej kolumny.
Jeśli zaczynasz od dokumentacji to może być ciężko na początku. Lepiej zaopatrz się w jakąś książkę, a to co jest w internecie przyda Ci się dopiero jak już będziesz miał solidne podstawy.
Nadal mam problem. Przy próbie zapisu nowego rekordu do tabeli user mam błąd, w którym mam info odnośnie nieistniejącego pola passwd (z tabeli user) w tabeli task. Nie wiem dlaczego pole z tabeli user jest szukane w task - nadal wygląda to na błędną relację. Kod mam taki sam jaki podałeś z małą różnicą:
has_many :task, :foreign_key => "responsible_id"
bo u mnie tabela nazywa się task i mam pluralize_table_names = false.
Konkretnie dostaje błąd: ‘undefined method `passwd=’ for #Task:0x415ed6c’
[quote=bukox]Nadal mam problem. Przy próbie zapisu nowego rekordu do tabeli user mam błąd, w którym mam info odnośnie nieistniejącego pola passwd (z tabeli user) w tabeli task.
Konkretnie dostaje błąd: ‘undefined method `passwd=’ for #Task:0x415ed6c’[/quote]
Pokaż kod który tworzy obiekt Task.
Podejrzewam, że w zmiennej ‘data’ (metoda self.create) przekazujesz niepoprawne dane, w szczególności klucz o nazwie “passwd”. Stąd błąd o nieznanej metodzie “passwd=”.
Ale problem dotyczy nie dodawania task’a bo to akurat działa prawidłowo a dodania usera i dlatego wydaje mi się, że winne są relacje bo co ma dodawanie usera do task’a i to jeszcze w taki dziwny sposób?
A to źle Cię zrozumiałem. Pokaż więc kod klasy User oraz kod tworzący obiekt usera. Relacje nie powinny mieć to wpływu (chyba że używasz np validates_associated_of …). Btw, próbowałeś z konsoli dodać nowego usera?