has_many i through

Witam,

mam taki model bazy: model

Użytkownik może mieć jedną książkę w danym momencie dodatkowo przechowywana jest historia tego co miał.

modele:

[code]class User < ActiveRecord::Base

belongs_to :book
has_many :books, :through => :books_users
end

class Book < ActiveRecord::Base
has_many :users
has_many :users_with_books, :through => :books_users, :source => :user

end[/code]
konsola:

[code]>>user = User.find(:first) # ok

user.book # ok, pokazuje mi książkę którą aktualnie posiada
user.books_users # błąd[/code]

  1. Czy kod, który podałem jest poprawny ? (wyczytałem ze HABTM nie jest dobrym rozwiązaniem)
  2. Jak się dostać do user.books_users ?

Pozdrawiam

Specem to ja jeszcze nie jestem ale jak bym próbował to szybciej tak :

user.books          ?

i sprawdź czy model BooksUser ma :

belongs_to :user belongs_to :book

Kod nie jest poprawny. Źle interpretujesz opcję :through. Opcja ta nie odnosi się do nazwy tabelki tylko do nazwy asocjacji. Asocjacji, której u Ciebie nie ma (:books_users). Sugeruję też inaczej nazwa asocjacje by odróżnić fakt, że użytkownik ma aktualnie jedną (bądź 0) wypożyczonych książek oraz historię książek, które pożyczył kiedyś. Kolejna sprawa to nazwa dla modelu pośredniczącego (u Ciebie tabelka books_users). Ponieważ podejście habtm nie jest zalecane (co nie znaczy, że nie można w ogóle z niego skorzystać) dobrze jest skorzystać z has_many :through (tak jak u Ciebie). Ponieważ to podejście wymusza stworzenie osobnego, pełnoprawnego modelu dobrze jest zastanowić się nad jego nazwą. “BooksUser” kompletnie nic nie mówi (prócz tego, że ma coś wspólnego z Book i User). Zadaj sobie więc pytanie: jak nazwiesz fakt wypożyczenia (oddania, przeczytania, zwrócenia?) przez użytkownika książki w przeszłości? Do głowy przychodzi mi: Wypożyczenie, Przeczytanie, Oddanie, Zwrot (mam kłopot z dobrym przetłumaczeniem:)). Proponuję więc Return (zwrot). Zwróc także na nazwy asocjacji. Nazywaj je tak by mówiły dokładnie o co chodzi (np. “książka ma wielu czytelników” chyba lepsze niż “książka ma wielu użytkowników”).

[code=ruby]class Book < ActiveRecord::Base
has_one :owner, :class_name => ‘User’
has_many :returns
has_many :readers, :through => :returns, :source => :user
end

class Return < ActiveRecord::Base
belongs_to :user
belongs_to :book
end

class User < ActiveRecord::Base
belongs_to :book
has_many :returns
has_many :read_books, :through => :returns, :source => :book
end[/code]

EDIT:

Poradziłem sobie z problemem. Dzięki :slight_smile:

PS: jak na forum zapisywać kod RUBY bo miedzy [ code ] a [/ code ] wyświetla “normalnie”

[ code=“ruby” ] Twój kod [/ code ]

Chciałbym pobrać nazwę książki zwróconej i datę zwrócenia. W

[code=“ruby”]>>user = User.find(:first)

user.read_books[/code]
jest id i nazwa książki. Jak pobrać dodatkowo datę z tabeli books_users ?