1. ホーム
  2. ruby-on-rails

[解決済み】Rails: railsのモデルのデフォルトのソート順?

2022-04-04 10:56:23

質問

モデルでデフォルトのソート順を指定したい。

を実行したときに .where() を指定せずに .order() では、デフォルトのソートが使用されます。しかし、もし私が .order() を指定すると、デフォルトを上書きしてしまいます。

解決方法は?

default_scope

Rails 4+で動作します。

class Book < ActiveRecord::Base
  default_scope { order(created_at: :desc) }
end

Rails 2.3, 3 の場合、代わりにこれが必要です。

default_scope order('created_at DESC')

Rails 2.x用。

default_scope :order => 'created_at DESC'

ここで created_at は、デフォルトで並べ替えを行いたいフィールドです。

ASC は、昇順に使用するコードであり <サブ DESC は降順の場合 ( desc , NOT dsc !).

scope

これに慣れたら、さらに scope :

class Book < ActiveRecord::Base
  scope :confirmed, :conditions => { :confirmed => true }
  scope :published, :conditions => { :published => true }
end

Rails 2 では、以下のものが必要です。 named_scope .

:published スコープを使用すると Book.published の代わりに Book.find(:published => true) .

Rails 3以降では、これらのメソッドをピリオドでつなげて「連結」することができるようになりました。 Book.published.confirmed .

この方法では、実際に結果が必要になるまでクエリは実行されません(遅延評価)。したがって、7つのスコープを連結しても、実際のデータベースクエリは1つだけとなり、7つの別々のクエリを実行することによるパフォーマンスの問題を回避することができます。

日付やuser_idのようなパラメータ(実行時に変更されるため、「遅延評価」が必要となるもの)を、このようにラムダで使用することができます。

scope :recent_books, lambda 
  { |since_when| where("created_at >= ?", since_when) }
  # Note the `where` is making use of AREL syntax added in Rails 3.

最後に、デフォルトのスコープを無効化します。

Book.with_exclusive_scope { find(:all) } 

あるいはもっといい。

Book.unscoped.all

で、フィルタ(条件)やソート(並び順)が無効になります。

最初のバージョンはRails2+で動作しますが、2番目のバージョン(unscoped)はRails3+のみであることに注意してください。


だから もしあなたが、ふーん、じゃあこれはメソッドのようなものなんだ、と思っているなら、そうです、まさにこれがスコープなのです!

これらは def self.method_name ...code... end しかし、ruby の場合と同様に、これらはちょっとした構文上のショートカット (または「シュガー」) で、物事を簡単にすることができます!

実際には、これらは「すべての」レコードの1つのセットに対して操作するので、クラスレベルのメソッドです。

しかし、その形式は変化しています。 rails 4では、呼び出し可能なオブジェクトを渡さずに#scopeを使用すると、非推奨の警告が表示されます。 例えば、scope :red, where(color: 'red')は次のように変更する必要があります。 scope :red, -> { where(color: 'red') } .

余談ですが、間違った使い方をすると デフォルト _scopeは誤用/悪用される可能性があります。

これは主に、以下のような動作に使用される場合についてです。 where を制限(フィルタリング)しています。 デフォルト を選択します。 <強い 悪知恵 は、単に結果の順序付けのために使われるのではなく、デフォルトのために使用されます。

については where を選択する場合は、通常の名前付きスコープを使用し、クエリでそのスコープを追加します。 Book.all.published ここで published は名前付きスコープです。

結論として、スコープは本当に素晴らしいもので、「太いモデル、細いコントローラ」というDRYerなアプローチのために、物事をモデルに押し上げるのに役立つのです。