[英]Specifying a WHERE clause after a JOIN clause - Active Record - CodeIgniter
[英]How to join tables and apply where clause for active record RAILS
这似乎是一件非常简单的事情,但是尽管查看了 rails 文档,但它并没有像我预期的那样工作。 我可能在某处做出了不正确的假设。 也许我正试图让 activerecord 用于它不打算用于的东西?
我正在尝试加入我的 Books 表和 Checkout_logs 表,并且只返回与 user_id 匹配且返回日期为 null 的记录(无)
我正在尝试在 sql 中执行类似此示例的操作(除了列出所有书籍信息,而不仅仅是标题并从参数中获取 user_id)
select b.title,c.due_date from
(select * from books) b
JOIN
(select * from checkout_logs) c
ON b.id = c.book_id
where c.user_id = 1 and returned_date is null
这是我的尝试
book_controller.rb
def my_books
@books = Book.joins(:checkout_logs).where(user_id: params[:user_id], returned_date: nil)
end
并查看
my_books.html.erb
<table>
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Subgenre</th>
<th>Pages</th>
<th>Publisher</th>
<th>due_date</th>
<th colspan="1"></th>
</tr>
</thead>
<tbody>
<% @books.each do |book| %>
<tr>
<td><%= link_to book.title, book %></td>
<td><%= book.author %></td>
<td><%= book.genre %></td>
<td><%= book.subgenre %></td>
<td><%= book.pages %></td>
<td><%= book.publisher %></td>
<td><%= book.due_date %></td>
<td><%= link_to 'Return', books_return_path %></td>
</tr>
<% end %>
</tbody>
</table>
书本.rb
class Book < ApplicationRecord
has_many :checkout_logs, dependent: :destroy
end
checkout_log.rb
class CheckoutLog < ApplicationRecord
belongs_to :user
belongs_to :book
end
在加载 book.user_id 不存在或 books.due_date 不存在的视图时会出错。 我知道书籍没有这些东西,但我认为通过将其与 checkout_log 加入我就可以通过这种方式访问它们?
我更愿意在 activerecord 中学习如何执行此操作,因为我认为这是最佳实践。 我愿意使用另一种方法。 我有另一个使用 AREL 执行类似操作的页面,但如果我可以学习如何更好地使用 activerecord,我更愿意清理它。
您可以通过将.to_sql
传递给查询来调试查询
@books =
Book
.joins(:checkout_logs)
.where(user_id: params[:user_id], returned_date: nil)
在这种情况下,我认为问题在于where
条件是针对books
表而不是checkout_logs
表。 你可以通过这样做来解决这个问题
.where(checkout_logs: { user_id: params[:user_id], returned_date: nil })
问题是 where 子句。 在 where 子句中,需要遍历关系才能访问正确表上的属性。 book 表上没有 user_id。 我假设返回的日期也在 CheckoutLog 表上。 如果您对此进行查询,则应该没问题。
Book.joins(:checkout_logs).where(checkout_logs: {user_id: params[:user_id], returned_date: nil})
要在此处获取结帐日志信息,您需要遍历关系。
@book.checkout_logs.each do |log|
puts log.due_date
...
end
执行上述操作的更好方法是使用包含和/或引用来急切加载相关的结帐日志以减少 n+1 问题
如果您只想要 CheckoutLog 记录,那么您需要从 model 开始。
CheckoutLog.where(book_id: <BOOK ID>, user_id: params[:user_id], returned_date: nil)
然后,您可以遍历视图中的那些,以获取您需要的任何结帐日志信息。
所以我需要在
book_controllers.rb
@checkout_logs = CheckoutLog.joins(:book).where(checkout_logs: {user_id: current_user.id, returned_date: nil})
然后视图可以通过执行以下操作访问这本书:
my_books.html.erb
<% @checkout_logs.each do |checkout_log| %>
<tr>
<td><%= checkout_log.book.title %></td>
<td><%= checkout_log.book.author %></td>
<td><%= checkout_log.book.genre %></td>
<td><%= checkout_log.book.subgenre %></td>
<td><%= checkout_log.book.pages %></td>
<td><%= checkout_log.book.publisher %></td>
<td><%= checkout_log.due_date %></td>
<td><%= link_to 'Return', books_return_path(:checkout_log_id => checkout_log.id) %></td>
</tr>
<% end %>
因为 checkout_log 有 1 本书,所以我可以通过这种方式访问这本书。 我无法以其他方式访问信息,也无法创建一些将所有信息都放在同一级别上的混合体。 (至少我做不到)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.