Ruby on Rails:用户有很多歌曲,一首歌有很多反馈,显示用户歌曲的所有反馈

时间:2016-06-08 03:07:14

标签: ruby-on-rails ruby

我是铁杆新手,所以请原谅不良技能和命名法。

我有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.

但这不起作用。

2 个答案:

答案 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复数形式:)。