2012-03-11 61 views
0

我试图让will_paginate的:order与这一类的工作:如何让will_paginate的命令与这个array.map一起工作?

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

眼下,没关系我给:order什么价值,职位由标签排序(我想创立之日起的标签)。我希望他们根据帖子创建日期显示。我认为问题在于will_paginate使用标签作为参考,而不是帖子。

如何解决这个问题(也许我必须以另一种方式定义@posts)?

附加信息:

用户可以订阅标签(​​因此在索引页的用户只能看到有标签的帖子,他或她是订阅)。

型号:

用户模式:

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 

标签型号:

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 

生成的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) 
+0

你能告诉我们生成的SQL? – Reactormonk 2012-03-11 16:27:20

+0

@Tass OK我添加了**生成的SQL ** – alexchenco 2012-03-12 03:28:51

回答

1

要调用paginate在常规数组上而不是在sql结果集上。

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

如果你是on Rails的3.1及以上版本:

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 

现在你可以

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

非常感谢!你能告诉我这一行发生了什么:'has_many:subscribed_posts,:source =>:posts,:through =>:subscribed_tags'?这一行解决了整个问题! – alexchenco 2012-03-12 03:40:38

+0

你的用例需要嵌套'has_many:through'。观看此轨道投下更多详细信息http://railscasts.com/episodes/265-rails-3-1-overview – 2012-03-12 05:42:01

+1

还要注意,使用新的解决方案,您正在减少N + 1的SQL语句问题。而不是为每个订阅的标签执行一个sql语句,而是为整个集合执行一条SQL语句。 – 2012-03-12 05:43:46

相关问题