次のクラスがあるとしましょう
_class SolarSystem < ActiveRecord::Base
has_many :planets
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_Sun > ?', 5).order('diameter ASC')
end
_
Planet
のスコープは_life_supporting
_およびSolarSystem
_has_many :planets
_です。 has_many関係を定義して、関連するすべてのplanets
に対して_solar_system
_を要求すると、_life_supporting
_スコープが自動的に適用されるように定義したいと思います。基本的に、_solar_system.planets == solar_system.planets.life_supporting
_が欲しいです。
notPlanet
の_scope :life_supporting
_を変更したい
default_scope where('distance_from_Sun > ?', 5).order('diameter ASC')
また、SolarSystem
に追加する必要がないため、重複を防ぎたい
_has_many :planets, :conditions => ['distance_from_Sun > ?', 5], :order => 'diameter ASC'
_
次のようなものが欲しい
_has_many :planets, :with_scope => :life_supporting
_
@phoetが言ったように、ActiveRecordを使用してデフォルトのスコープを達成することは不可能かもしれません。ただし、2つの潜在的な回避策が見つかりました。両方とも重複を防ぎます。最初のものは長い間、明らかな読みやすさと透明性を維持し、2番目のものは出力が明示的なヘルパー型メソッドです。
_class SolarSystem < ActiveRecord::Base
has_many :planets, :conditions => Planet.life_supporting.where_values,
:order => Planet.life_supporting.order_values
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_Sun > ?', 5).order('diameter ASC')
end
_
よりクリーンな別の解決策は、単に次のメソッドをSolarSystem
に追加することです
_def life_supporting_planets
planets.life_supporting
end
_
また、_solar_system.life_supporting_planets
_を使用する場合はいつでも_solar_system.planets
_を使用します。
どちらも質問に答えないので、他の誰かがこの状況に遭遇した場合の回避策としてここにそれらを配置します。
Rails 4、Associations
には、scope
に適用されるラムダを受け入れるオプションのRelation
パラメーターがあります(cf. ActiveRecord :: Associations :: ClassMethods )
class SolarSystem < ActiveRecord::Base
has_many :planets, -> { life_supporting }
end
class Planet < ActiveRecord::Base
scope :life_supporting, -> { where('distance_from_Sun > ?', 5).order('diameter ASC') }
end
Rails 3、where_values
回避策は、where_values_hash
条件が複数のwhere
またはハッシュ(ここでは当てはまらない)によって定義される場合、より良いスコープを処理します。
has_many :planets, conditions: Planet.life_supporting.where_values_hash
Rails 5では、次のコードは正常に動作します...
class Order
scope :paid, -> { where status: %w[paid refunded] }
end
class Store
has_many :paid_orders, -> { paid }, class_name: 'Order'
end
activeRecordを詳しく調べたところ、現在のhas_many
の実装でこれを達成できるかどうかはわかりません。ブロックを:conditions
に渡すことができますが、これは条件のハッシュを返すことに制限されており、いかなる種類のアレルのものも返しません。
あなたが望むもの(あなたがしようとしていると思うこと)を達成するための本当にシンプルで透明な方法は、実行時にスコープを適用することです:
# foo.rb
def bars
super.baz
end
これはあなたが求めているものとはほど遠いですが、うまくいくかもしれません;)