简体   繁体   中英

How to make will_paginate's order to work with this array.map?

I'm trying to make will_paginate's :order to work with this array:

@posts = current_user.subscribed_tags.map(&:posts).flatten.paginate(:page => params[:page],
                                                   per_page => 5,
                                                   :order => "created_at DESC")

Right now, it doesn't matter what value I give to :order , posts are ordered by tag (I think the date of creation of the tag). I want them to appear according to the posts creation date. I think the problem is that will_paginate is using the tags as reference and not the posts.

How to solve this issue (Maybe I have to define @posts in another way)?

Additional Information:

Users can subscribe to tags (So in the index page the user only sees posts with tags he or she is subscribe to).

Models:

User model:

class User < ActiveRecord::Base

  (Devise)

  has_many :posts, :dependent => :destroy
  has_many :subscriptions
  has_many :subscribed_tags, :source => :tag, :through => :subscriptions

  attr_writer :subscribed_tag_names
  after_save :assign_subscribed_tags

  def subscribed_tag_names
    @subscribed_tag_names || subscribed_tags.map(&:name).join(' ')
  end

  private

  def assign_subscribed_tags
    #self.subscribed_tags = []
    return if @subscribed_tag_names.blank?
    @subscribed_tag_names.split(" ").each do |name|
      subscribed_tag = Tag.find_or_create_by_name(name)
      self.subscribed_tags << subscribed_tag unless subscribed_tags.include?(subscribed_tag)
    end
  end
end

Tag model:

class Tag < ActiveRecord::Base
  has_many :taggings, :dependent => :destroy  
  has_many :posts, :through => :taggings
  has_many :subscriptions
  has_many :subscribed_users, :source => :user, :through => :subscriptions

  def tag_posts_count
    "#{self.name} (#{self.posts.count})"
  end
end

Generated SQL:

Processing by PostsController#index as HTML
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "subscriptions" ON "tags"."id" = "subscriptions"."tag_id" WHERE "subscriptions"."user_id" = 2
  Post Load (0.7ms)  SELECT "posts".* FROM "posts" INNER JOIN "taggings" ON "posts"."id" = "taggings"."post_id" WHERE "taggings"."tag_id" = 6
  Post Load (0.6ms)  SELECT "posts".* FROM "posts" INNER JOIN "taggings" ON "posts"."id" = "taggings"."post_id" WHERE "taggings"."tag_id" = 10
  Post Load (0.7ms)  SELECT "posts".* FROM "posts" INNER JOIN "taggings" ON "posts"."id" = "taggings"."post_id" WHERE "taggings"."tag_id" = 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."post_id" = 42
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 4 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."post_id" = 38
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Comment Load (0.6ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 52 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 52 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  CACHE (0.0ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 52 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."post_id" = 52
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."post_id" = 55
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
  Comment Load (0.7ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 57 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 57 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  CACHE (0.0ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 57 ORDER BY "comments"."id" DESC LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."post_id" = 57
  Rendered layouts/_sidebar.html.erb (12.6ms)
  Rendered posts/index.html.erb within layouts/application (314.3ms)
  Rendered layouts/_header.html.erb (5.2ms)
  Rendered layouts/_footer.html.erb (0.1ms)
Completed 200 OK in 1242ms (Views: 392.8ms | ActiveRecord: 12.5ms)

You are calling paginate on a regular array rather than on a sql result set.

[1,2,3,4].paginate(:page => 1, :per_page => 2) # [1, 2]
current_user.subscribed_tags.map(&:posts) # returns an array

If you are on Rails 3.1 and above:

class User < ActiveRecord::Base
  has_many :posts, :dependent => :destroy
  has_many :subscriptions
  has_many :subscribed_tags, :source => :tag, :through => :subscriptions
  has_many :subscribed_posts, :source => :posts, :through => :subscribed_tags
end

class Subscription
  belongs_to :user
  belongs_to :tag
end  

class Tag < ActiveRecord::Base
  has_many :taggings, :dependent => :destroy  
  has_many :posts, :through => :taggings
  has_many :subscriptions
end

Now you can

current_user.subscribed_posts.paginate(:page => params[:page],
  per_page => 5,
  :order => "created_at DESC")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM