【问题标题】:How to make a path to a paginated url?如何创建分页网址的路径?
【发布时间】:2015-05-09 00:23:14
【问题描述】:

当用户 #1 对用户 #2 点赞/cmets 时,用户 #2 会收到通知:

notifications/_notifications.html.erb

<%= link_to "", notification_path(notification.id), method: :delete, class: "glyphicon glyphicon-remove" %> <%= link_to Comment.find_by(notification.comment_id).user.name, user_path(Comment.find_by(notification.comment_id).user.id) %> commented on <%= link_to "your activity", (notification.activity_id) %>

但是当用户 #2 单击通知时,它不会导致任何地方,因为我删除了 activity_path,如果我将它放回 (notification.activity_id) 之前,我们会收到一个错误:

没有路线匹配 {:action=>"show", :controller=>"activities", > :id=>nil} 缺少必需的键:[:id]

我不知道这是否可能,但点击通知后,用户#2 将被带到活动所在的分页页面。通过gem will_paginate 每页有 20 个活动,因此如果评论的活动在第 2 页上,那么在单击活动后,用户 #2 应被定向到:http://0.0.0.0:3000/activities?page=2

这至少会缩小评论在用户活动源上的位置。

activities/index.html.erb

<% @activities.each do |activity| %>
    <%= link_to activity.user.name, activity.user %>
    <%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>

      <% activity.activity_likers.each do |user| %>
          <%= user.name %>
      <% end %>

    <%= link_to like_activity_path(:id => activity.id), class: "btn", method: :post do %>
      <span class='glyphicon glyphicon-thumbs-up'></span> Like
    <% end %>

    <%= render "comments/comments", comments: activity.comments %>
    <%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>

<% end %>

<%= will_paginate @activities %>

activities_controller.rb

class ActivitiesController < ApplicationController
    def index
        @activities = Activity.order("created_at desc").paginate(:page => params[:page], :per_page => 20)
    end

    def show
          redirect_to(:back)
    end
end

如果您发现可以这样做,如果您需要更多代码,请告诉我:)

更新

class NotificationsController < ApplicationController
    def index
    @notifications = current_user.notifications
    @notifications.each do |notification|
        notification.update_attribute(:read, true)
        activity = Activity.find(notification.activity_id) #Gives "Couldn't find Activity with 'id'=". I then removed ".activity_id" to see what happens next.
            index    = Activity.order(created_at: :desc).index(activity)
            page_number = (index / per_page.to_f).ceil #I am then told "undefined local variable or method `per_page'" so I tried making it :per_page to which I then get: "undefined method `to_f' for :per_page:Symbol"
    end
    end


    def destroy
      @notification = Notification.find(params[:id])
      @notification.destroy
      redirect_to :back
    end
end

routes.rb

resources :activities do
  resources :comments
  resources :notifications
  member do
    post :like
    post :notifications
  end
end

更新 #2

通知/index.html.erb

    <% if !@notifications.blank? %>
        <%= render partial: "notifications/notification", collection: @notifications %> 
    <% else %>
        <p>No notifications... yet</p>
    <% end %>

comment.rb

class Comment < ActiveRecord::Base
    after_create :create_notification
  has_many :notifications
  has_many :comment_likes   
  has_many :likers, through: :comment_likes, class_name: 'User', source: :liker
    belongs_to :commentable, polymorphic: true
    belongs_to :user
  belongs_to :activity

private

  def create_notification
    @activity = Activity.find_by(self.activity)
    @user = User.find_by(@activity.user_id).id
      Notification.create(
       activity_id: self.activity,
       user_id: @user,
       comment_id: self,
       read: false
      )
  end
end

_create_notifications.rb

class CreateNotifications < ActiveRecord::Migration
  def change
    create_table :notifications do |t|
      t.references :activity, index: true
      t.references :comment, index: true
      t.references :user, index: true
      t.boolean :read

      t.timestamps null: false
    end
    add_foreign_key :notifications, :activities
    add_foreign_key :notifications, :comments
    add_foreign_key :notifications, :users
  end
end

【问题讨论】:

  • 第一件事,所以不考虑你的第二个问题......当你将你的 URL 更改为 activity_path(notification.activity) 时,你仍然有错误吗?

标签: ruby-on-rails ruby model-view-controller pagination will-paginate


【解决方案1】:

要确定activity 位于哪个页面,您可以执行以下操作:

activity = Activity.find(notification.activity_id)
index    = Activity.order(created_at: :desc).index(activity)

以上将确定所有活动中activity 中的index

所以,假设您有 85 个活动。每页有 20 个活动,所以在这种情况下,您将有 5 页,对吗?好吧,假设上面的 index 返回 42。要计算页码,您必须这样做(假设您有一个名为 per_page 的变量,即 20):

page_number = (index / per_page.to_f).ceil

你有index 42。你必须将它除以每页的活动数(它需要是一个浮点数!),那就是20.0 .这导致2.1ceil 那你就有了你的页码,应该是 3。

所以,要创建正确的分页路径,您现在可以这样做:

activities_path(page: page_number)

更新

现在我们知道activity_id 没有正确设置在notification 上,我们可以解决这个问题(还要注意comment_id 也没有设置)。将 Comment 模型的最后一部分更改为:

...

belongs_to :activity

validates :activity_id, presence: true
validates :user_id, presence: true

private

def create_notification
  Notification.create(activity_id: self.activity_id, user_id: self.user_id, comment_id: self.id, read: false)
end

我在此处添加了两个验证,以确保设置了 activity_iduser_id。现在正如我之前所说,comment_id 也没有设置。那是因为id 仅分配给save,在create 上您只是将其设置为保存。因此,将after_create :create_notification 更改为after_save :create_notification 以便能够设置comment_id

这应该设置activity_idcomment_id。现在进行下一部分。获取正确的页码,该页码应添加到您的 _notification.html.erb 部分链接中。

将这些方法添加到您的 Activity 类中:

def page_number
  (index / per_page.to_f).ceil
end

private

def index
  Activity.order(created_at: :desc).index self
end

现在将 notifications/_notification.html.erb 部分中的路径更改为:

activities_path(page: notification.activity.page_number)

注意:如果您在page_number 方法中收到有关per_page 的错误,您可能没有在模型本身中设置值per_page(如this;基本上将self.per_page = 20 添加到您的模型中正下方class Activity &lt; ActiveRecord::Base)

如果您决定这样做,您可以删除ActivitiesController 中的, :per_page =&gt; 20 部分。如果不是,只需将per_page.to_f 替换为20.to_f20.0

此外,从您之前注释掉的 NotificationsController 中删除 3 行,以了解是否设置了 activity_id。您不再需要它们,因为我们已将它们放在 Activity 类中。

【讨论】:

  • 嘿,如果您有 10 分钟(最多),我很乐意为您解答一些我在使用您的一些代码时遇到的小问题。你愿意堆叠聊天、Skype、Facetime、Gotomeeting 或任何适合你的东西吗?
  • 你想知道什么?你想知道这段代码属于哪里吗?你提到你有一个notifications/_notifications.html.erb 部分。所以,我猜你有一个NotificationsController 和一个show 操作。这段代码属于那里。除此之外,activity_path 有错误。我认为您根本不应该链接到show 视图,your activity 链接应该只是链接到activities_path(page: page_number),其中page_number 是在NotificationsController#show 操作中计算的。
  • 嘿,好吧,NotificationsController 中没有 show 操作,但有一个 index 操作。我在那里尝试更新了问题。有了我不知道的错误。也许它与配置有关。那里也更新了。然后我遇到了page_number 的错误。然后我尝试了:page_number,但这也给了我一个错误。有问题的进一步解释:)
  • 好的,首先。你如何在你的notifications/_notifications.html.erb 部分中获得notification?您是否有 notifications/index.html.erb 包含 _notifications.html.erb 部分?如果是这样,它看起来像什么?另外,这些notifications 是如何创建的?您的NotificationsController 中有newcreate 操作吗?我已经用一个小修复(只是其中的一部分)更新了我的答案,这可能会起作用。
  • 前两个问题是。更新的问题。我还按照本教程为我的“活动”evanamccullough.com/2014/11/… 更改了他的“帖子”,但无需单击它,因为我还更新了创建这些通知的位置的问题。回答最后一个问题,不。我已经展示了完整的通知控制器。我尝试了您的修复,但这对我也不起作用,给了我与以前相同的错误消息:Couldn't find Activity with 'id'=
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
相关资源
最近更新 更多