【问题标题】:I have a has_many relationships and I want to set custom limit and offset. as well as to count them我有一个 has_many 关系,我想设置自定义限制和偏移量。以及计算它们
【发布时间】:2010-03-30 16:03:42
【问题描述】:

喂,

我的代码:

@profile.images

我想一次只获得 10 张图像,偏移量为 10,像这样

@profile.images(:limit => 10, :offset => 10)

不是这样的

has_many :images, :limit => 10, :offset => 10

然后我想以某种方式计算该个人资料的所有图像。

@profile.count_images

谢谢(:


has_many :images, :foreign_key => 'on_id', :conditions => 'on_type = "profile"' do
def paginate(page = 1, limit = 10, offset = nil)
  page = nil if page < 1
  limit = 1 if limit < 1
  offset = 0 if(offset && offset < 0)
  offset = 0 if (!page)
  offset = limit * (page - 1) if (page)

  all(:limit=> limit, :offset => offset)
end

结束

现在我想将此行为添加到其他 has_many 关系中。但我不想复制粘贴代码......知道吗? :P

【问题讨论】:

    标签: ruby-on-rails count limit has-many offset


    【解决方案1】:

    使用关联扩展:

    class Profile < ActiveRecord::Base
      has_many :images do
        def page(limit=10, offset=0)
          all(:limit=> limit, :offset=>offset)
        end
      end
    end
    

    现在你可以使用page方法如下:

    @profile.images.page # will return the first 10 rows
    @profile.images.page(20, 20) # will return the first 20 rows from offset 20
    @profile.images # returns the images as usual
    

    编辑

    在这种特定情况下,关联函数可能是一个合适的选择。甚至带有 named_scope 的 lambda 也可以工作。如果您在Profile 类上定义它,您将失去named_scope 的可重用方面。您应该在图像类上定义 named_scope。

    class Image < ActiveRecord::Base
    
      named_scope :paginate, lambda { |page, per_page| { :offset => ((page||1) -1) * 
                                  (per_page || 10), :limit => :per_page||10 } }
    
    end
    

    现在您可以将此命名范围与关联一起使用:

    @profile.images.paginate(2, 20).all
    

    或者你可以直接在Image类上使用named_scope

    Image.paginate(2, 20).all(:conditions => ["created_at > ?" , 7.days.ago])
    

    另一方面,你为什么不使用will_paginate 插件?

    【讨论】:

    • 谢谢,这好多了。我知道了,但不是很酷:named_scope :paginate, lambda { |page, limit, offset| {:limit => 限制 || 10, :offset => 偏移量 || ((limit || 10) * ( page - 1 ) )}} 非常感谢!现在我会试试看;)
    • 是的,使用遗嘱分页可能会更好。我现在就去学一些。无论如何,谢谢你。它可以帮助其他事情......
    【解决方案2】:

    您可以使用with_scope 将您的调用范围限定为@profile.images,并在范围之外执行计数。

    Image.with_scope(:find => { :limit => 10, :offset => 10 }) do
      @profile.images      # load association using limit and offset
    end
    
    @profile.images.reset  # reset cached association, else size would return <=10
    @profile.images.size   # go to the database again for a real COUNT(*)
    

    【讨论】:

    • 谢谢。你给了我一个新想法:named_scope :limit, lambda { |num| { :limit => num } } named_scope :offset, lambda { |num| { :limit => num } } 然后@profile.images.limit(10).offset(10)
    猜你喜欢
    • 2011-05-25
    • 2018-11-07
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多