我是铁杆新手,所以请原谅不良技能和命名法。
我有3个模特。
用户 歌曲 反馈
在用户的个人资料中,我想显示:
现在我在控制器中这样做:
@RequestBody
然后在我看来,我实际上访问了用户收到的反馈:
def show
@user = User.friendly.find(params[:id])
@songs = @user.songs.paginate(:page => params[:song_page], :per_page => 5)
@feedbacksGiven = @user.feedbacks.paginate(:page => params[:feed_page], :per_page => 10)
@feedbacksReceived = @user.songs.paginate(:page => params[:feed_received_page], :per_page => 10)
end
但是,这显示了按歌曲分组的每个反馈。我想在哪里能够根据created_by以降序显示所有反馈。这种方法也与will_paginate方法混淆。
有更简单的方法吗?
我希望能够做的基本前提是:
<% @feedbacksReceived.each do |song| %>
<% if song.feedbacks.any? %>
<% @userFeeds = song.feedbacks.all() %>
<% @userFeeds.each do |feed| %>
etc.
但这不起作用。
答案 0 :(得分:2)
有一些事情需要学习,所以我会尽力覆盖每一个。首先看起来你想要用户歌曲的反馈,所以一个好方法是include
查询中的数据@user.songs
。
@songs = @user.songs.includes(:feedbacks).paginate(:page => params[:song_page], :per_page => 5)
然后在你看来
@songs.each do |song|
song.feedbacks.each do |feedback|
# Do stuff with that feedback
end
end
使用包含的原因是您没有进行N + 1次查询。您还应该避免在视图中进行数据库查询,这是一种不好的做法。
上述解决方案并未对反馈进行分页,这是一个单独的问题,当您想要对一组对象执行此操作时可能会非常棘手。通常,您将子对象的集合分页到单个父对象。原因是,如果您在第2页的反馈意见中这意味着您想要返回该集合中所有歌曲的第二页反馈,还是只返回特定的一首?
注意:我可能错误地使用feedbacks
而不是feedback
。我不确定rails会如何复数Feedback
这在技术上是单数和复数形式的单词。
我要做的最后一个注意事项是,我建议使用一些jquery或其他前端代码来命中每首歌曲的js端点。这样,您实际上可以查询传递歌曲ID的单个端点和反馈的分页参数。它会使应用程序更加健壮,但也是一种更先进的解决方案。
答案 1 :(得分:0)
你想要feedbacks
,所以你需要询问/查询feedbacks
,所以你需要反过来这样做,如下:
@feedbacksReceived = Feedback.joins(:song).where(:songs => { :user_id => @user.id }).order(:created_by => :desc).
paginate(:page => params[:feed_received_page], :per_page => 10)
但是使用关联有一种更简单的方法,只需添加has_many :through
关联:
# in the user model:
has_many :feedbacks_received, :through => :songs, :source => :feedbacks
# in the controller:
@feedbacksReceived = @user.feedbacks_received.order(:created_by => :desc).
paginate(:page => params[:feed_received_page], :per_page => 10)
注意:未经测试,我也可能错误地使用feedbacks
复数形式:)。