ActiveRecord Query Interface 3.0

この翻訳では、Ruby on Rails 3のActiveRecrodの次のバージョンでの革新について説明し、新しいインターフェイスのサポートを優先して除外されるモジュールの部分についても説明します。



Rails 3.1でサポートが失われるものは何ですか?



次のメソッドはRails 3.1のリリースで非推奨と見なされ(Rails 3.0ではありません)、Rails 3.2から完全に除外されます(ただし、特別なプラグインをインストールして使用することもできます)。 この警告に留意してください。 コードの大幅な変更が必要です。



要するに、 :conditions



:include



:joins



:limit



:offset



:order



:select



:readonly



:group



having



:from



:lock



ActiveRecordによって提供される任意のクラスメソッド:lock



含むoptions



ハッシュを渡すomは廃止されたと見なされます。



これをより詳細に検討してください。 ActiveRecordは現在、次の検索方法を提供しています。 計算方法と同様に: Rails 3.0以降、これらのメソッドにオプションを渡すことは推奨されておらず、Rails 3.2では完全に削除されます。 さらに、メソッドfind(:first)



およびfind(:all)



(追加オプションなし)も除外され、 first



およびall



が優先されall



。 ルールの例外として、 count()



は引き続き:distinct



オプションを受け入れます。



次のコードは、サポートされていないオプションの使用を示しています。
User.find(:all, :limit => 1)

User.find(:all)

User.find(:first)

User.first(:conditions => {:name => 'lifo'})

User.all(:joins => :items)






ただし、このコードは引き続き機能します。
User.find(1)

User.find(1,2,3)

User.find_by_name('lifo')






さらに、オプションハッシュをnamed_scope



メソッドに渡すと、サポートも失われます。

named_scope :red, :conditions => { :colour => 'red' }

named_scope :red, lambda {|colour| {:conditions => { :colour => colour }} }







オプションの転送は、メソッドwith_scope



with_exclusive_scope



およびdefault_scope



サポートも失います:

with_scope(:find => {:conditions => {:name => 'lifo'}) { ... }

with_exclusive_scope(:find => {:limit =>1}) { ... }

default_scope :order => "id DESC"







動的scoped_by_



も同様に履歴に記録されます。
red_items = Item.scoped_by_colour('red')

red_old_items = Item.scoped_by_colour_and_age('red', 2)






新しいAPI



Rails 3のActiveRecordは、以下の検索メソッドを受け取ります( options



ハッシュの既存の同等物は括弧内に示されています)。
チェーン


上記の各メソッドは、 Relation



クラスのオブジェクトを返します。 基本的に、 Relation



匿名のnamed_scope



に非常に似ています。 これらのメソッドはすべて自分で定義されているため、呼び出しのチェーンを作成できます。
lifo = User.where(:name => 'lifo')

new_users = User.order('users.id DESC').limit(20).includes(:items)






既存のリレーションに複数のファインダーを適用することもできます。
cars = Car.where(:colour => 'black')

rich_ppls_cars = cars.order('cars.price DESC').limit(10)






ほぼモデル


プライマリCRUDメソッドの使用に関しては、リレーションはモデルとまったく同じように動作します。 次のメソッドは、Relationクラスのオブジェクトで呼び出すことができます。 次のコードは期待どおりに機能します。

red_items = Item.where(:colour => 'red')

red_items.find(1)

item = red_items.new

item.colour #=> 'red'



red_items.exists? #=> true

red_items.update_all :colour => 'black'

red_items.exists? #=> false






update



またはdelete



/ destroy



メソッドを呼び出すと、 Relation



が「リセット」されることを知っておくことが重要です。 メソッドを最適化するために使用されるキャッシュエントリ( relation.size



など)を削除します。



遅延読み込み


おそらく前の例から、 Relations



「怠lazに」ロードされることがすでに明らかになっています-つまり それらについては、コレクションを操作するメソッドを呼び出す必要があります。 これは、 associations



named_scope



すでに機能している方法に非常に似ています。
cars = Car.where(:colour => 'black') # Relations ,

cars.each {|c| puts c.name } # "select * cars ..."






これは、フラグメントキャッシングと共に非常に便利です。 そのため、コントローラーでは次を呼び出すだけで十分です。

def index

@recent_items = Item.limit(10).order('created_at DESC')

end




そしてビューで:

<% cache('recent_items') do %>

<% @recent_items.each do |item| %>

...

<% end %>

<% end %>






前の例で@recent_items



@recent_items.each



view



から@recent_items.each



れた場合にのみ、データベースから@recent_items



生成されview



。 コントローラーはデータベースからのクエリを実行しないため、追加の作業を必要とせずに断片化されたキャッシングがはるかに効率的になります。



強制ダウンロード- all



first



last





遅延読み込みが不要な場合は、たとえば、 all



Relation型のオブジェクトで呼び出す必要があります。

cars = Car.where(:colour => 'black').all





ここではall



Relation



ではなくArray



返すことを覚えておくことが重要です。 これは、Rails 2.3でnamed_scope



associations



がどのようにnamed_scope



するかに似ています。

同様に、 first



last



メソッドはタイプActiveRecord



(またはnil



)のオブジェクトを返します:

cars = Car.order('created_at ASC')

oldest_car = cars.first

newest_car = cars.last






named_scope



scope





named_scope



メソッドの使用は、 named_scope



を支持して、Rails 3.0では推奨されません。
しかし、実際に変更されたのは、 named_



プレフィックスを記述する必要がなくなったことnamed_



です。
渡す検索オプションは、Rails 3.1から完全に除外されます。

named_scope



メソッドは、単にscope



という名前に変更されました。 つまり 次の定義:

class Item

named_scope :red, :conditions => { :colour => 'red' }

named_scope :since, lambda {|time| {:conditions => ["created_at > ?", time] }}

end






次のようになります。

 クラスItem
    スコープ:赤、:条件=> {:色=> '赤'}
    スコープ:以来、ラムダ{|時間|  {:条件=> ["created_at>?"、時間]}}
終わり 


ただし、オプションハッシュが除外されるという事実を考慮すると、実際には新しい検索方法を使用して記述する必要があります。 このように:

 クラスItem
    スコープ:赤、ここで(:色=> '赤')
    スコープ:以来、ラムダ{|時間|  where( "created_at>?"、time)}
終わり 


内部的には、 named scope



Relation



アドオンであり、 finder



メソッドと組み合わせて使用​​するための非常に単純なバリエーションを作成します。

red_items = Item.red

available_red_items = red_items.where("quantity > ?", 0)

old_red_items = Item.red.since(10.days.ago)






Model.scoped





「クリーンな」リレーションから始まる複雑なクエリを作成する必要がある場合は、 Model.scoped



使用する必要があります。

cars = Car.scoped

rich_ppls_cars = cars.order('cars.price DESC').limit(10)

white_cars = cars.where(:colour => 'red')






内部といえば、 ActiveRecord::Base



には次のデリゲートが含まれています。

delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped

delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped

delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped






上記のコードは、 ActiveRecord



内で行われていることのより透明なビューを提供できます。 これに加えて、動的メソッド(別名find_by_name



find_all_by_name_and_colour



)もRelation



によって委任されます。



with_scope



およびwith_exclusive_scope





with_scope



with_exclusive_scope



Relation



'aの上に構築され、それらとの関係を使用できるようになりました。

  with_scope(where(:name => 'lifo'))do
    ...
終わり 


または名前付きスコープ:

  with_exclusive_scope(Item.red)do
    ...
終わり 



All Articles