2012-03-11 66 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

相關問題