has_many通过需要通过类的属性

时间:2014-02-09 13:41:06

标签: ruby-on-rails

我有三种模式:

User id, name, ...
  has_many :user_books
  has_many :books, through: :user_books

Books id, name, author 
  has_many :user_books

UserBooks id, user_id, book_id, has_read, rating
  belongs_to :user
  belongs_to :book

好的,这就是设置。当我做User.books时,我得到了一系列书籍,但是无法访问在UserBooks中设置的属性(book.name,book.author),例如has_read,rating等。

如何阅读书籍和用户书

1 个答案:

答案 0 :(得分:0)

您要做的是使用连接模型,执行以下操作。在控制器中:

@user_books = @user.user_books.includes(:books)

(使用包含可以防止n+1 queries问题,因为它会缓存user_books所需的书籍,导致总共2次查询)

然后在视图中,您可以执行以下操作:

<%= @user_books.each do |user_book| %>
  <div class="<%= 'read' if user_book.has_read? %>">
    <h2><%= user_book.book.name %> <small>by <%= user_book.book.author %></h2>
    <span><%= user_book.rating %></span>
  </div>
<%= end %>

如果您想要包含本书的方法,可以使用delegate,如下所示:

class UserBook < ActiveRecord::Base
  belongs_to :user
  belongs_to :book

  delegate :has_read, to: :book
  delegate :author, to: :book
end

http://api.rubyonrails.org/classes/Module.html#method-i-delegate

然后你可以做到以下几点:

@books = @user.user_books.includes(:books)

然后在视图中:

<%= @books.each do |book| %>
  <div class="<%= 'read' if book.has_read? %>">
    <h2><%= book.name %> <small>by <%= book.author %></h2>
    <span><%= book.rating %></span>
  </div>
<%= end %>

现在理解虽然我们在控制器和视图中称它为“Book”,但它是一个“UserBook”对象。