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]