0

2 つの単純なリレーション ヘルパーを作成しました。

  • with_preferred_sort_orderリレーションを返します
  • all_on_page戻り値[pages_count, record_array]

with_preferred_sort_order は奇妙なことにレコードをソートします:

1.9.3p194 :040 > Article.with_preferred_sort_order.
all_on_page(1).last.map{|a| puts a.title[0..20]};nil
  (0.5ms)  SELECT COUNT(*) FROM "articles" 
  Article Load (157.9ms)  SELECT "articles".* FROM "articles" 
ORDER BY title Desc LIMIT 50 OFFSET 0

“The Bar for Success 
method_missing in Jav
jQuery on Rails: A Fr
jQuery in Action (w00
jQuery in Action (w00
jQuery Selector Refca
jQuery Selector Refca
jQuery Selector Refca
jQuery 1.4 and Malfor
jQuery 1.4 and Malfor
What’s Wrong with “HT
What’s Up With All Th
What’s Up With All Th
What’s Up With All Th
What’s Up With All Th
What’s New in Bundler
Vibrant Ink Theme for
Using the New Gem Bun
Using the New Gem Bun
Using SproutCore 2.0 
Using SproutCore 2.0 
Using SproutCore 2.0 
Using >= Considered H
Understanding “Protot
Understanding JavaScr
Tokaido: My Hopes and
Tokaido Status Update
Today’s Dispatch: Wea
Threads (in Ruby): En
Threads (in Ruby): En
Threads (in Ruby): En
The Rails 3 Router: R
The Rails 3 Router: R
The Irony of the iPad
Textmate gem
Textmate Search in a 
Stop Watching Sophie’
Spinning up a new Rai
Spinning up a new Rai
Some of the Problems 
Simplifying Rails Blo
Search within a folde
Ruby 2.0 Refinements 
Ruby 2.0 Refinements 
Ruby 2.0 Refinements 
RailsConf Talk Recap
RailsConf Slides
RailsConf Slides
RailsConf Slides
RailsConf Europe Slid
 => nil 
1.9.3p194 :041 > 

ソースはこちら

  def self.included recipient
    with recipient do
      scope :with_preferred_sort_order, 
        lambda { 
          #sort_by  = recipient.preferences.sort_by; 
          #asc_desc = recipient.preferences.asc_desc; 
          #recipient.order("%s %s"%[sort_by, asc_desc]) 
          sort_by  = preferences.sort_by; 
          asc_desc = preferences.asc_desc; 
          order("%s %s"%[sort_by, asc_desc]) 
        }
    end
  end

そしてもう一つ

module ActiveRecord
  class Relation
    # Returns an array [ pages_range, items_array]
    #   pages_range is a range of pages, which starts from 1, e.g. 1..19
    #   items_array is an array which contains items of page_number page
    #
    def all_on_page page_number=1, items_per_page=nil
      def total_pages items_qty, items_per_page
        r = items_qty/items_per_page
        r == 0 ? 1 : items_qty % items_per_page !=0 ? r+1 : r
      end

      items_per_page ||= self.klass.respond_to?(:preferences) ? 
        self.klass.preferences.items_per_page.to_i : 10
      items_qty = self.count

      pages_range = 1..total_pages(items_qty, items_per_page)
      offset      = (page_number - 1)*items_per_page
      items_array = self.offset(offset).limit(items_per_page).all

      [ pages_range, items_array ]
    end
  end
end
4

1 に答える 1

1

ここにはいくつかの問題があります。

  1. 最初のエントリは非 ASCII 文字で始まります (正確にはわかりませんが、標準の二重引用符ではありません)。これらは、標準の ASCII 文字の後に最後にソートされると思います。

  2. エントリを A から Z に並べ替えたいように見えますが、SQL ではORDER BY title Desc、Z から A に降順に並べ替える が指定されています。昇順の並べ替え (ORDER BY title ASCまたは単にORDER BY title) が必要です。これが、上記の非 ASCII 文字が下部ではなく上部に表示される理由でもあります。

  3. 指定されていませんが、並べ替えで大文字と小文字が区別されないことを期待しているようです。SQLite の標準的な照合シーケンスは BINARY で、ASCII 値に基づいてソートされます。大文字は小文字よりも小さい ASCII 値を持つため、大文字で始まるすべてのタイトルは、小文字で始まるすべてのタイトルの前に並べ替えられます。

照合シーケンスに関する SQLite のドキュメントを読んでください。タイトルを大文字と小文字を区別しない方法で並べ替えるには、NOCASE 照合順序を使用する必要があります。

...ORDER BY title COLLATE NOCASE...

COLLATE NOCASEまたは、テーブル定義のその列にステートメントを追加します。非 ASCII 文字をシーケンスのどこかに折り畳む場合は、カスタム照合シーケンスを定義する必要がある場合があります。

于 2012-10-15T13:09:47.473 に答える