まず第一に、はインスタンス メソッドであるためMyClass.all.some_action
動作しませんが、一方で-- を返します。そのため、実際に を呼び出していることになります。MyClass#some_action
MyClass#all
Array
MyClass.all.some_action
Array#some_action
また、異なるクラスに注意MyClass.all
して返します。MyClass.active
MyClass.active.class # => ActiveRecord::Relation
MyClass.active.all.class # => Array
あなたが何をsome_action
すべきかわかりません...あなたがやりたいと思うかもしれないいくつかのオプション:
オプション #1: データベース クエリの絞り込み
が配列をフィルタリングしている場合some_action
は、次のようにして、それをさらに別のスコープに変換する必要があります。
class MyClass < ActiveRecord::Base
scope :active, where(:status => 'active')
scope :inactive, where(:status => 'inactive')
scope :some_action, ->(color_name) { where(color: color_name) }
end
そして、 を使用して呼び出しますMyClass.active.some_action('red').all
。最初の結果だけが必要な場合は、MyClass.active.some_action('red').first
.
scope
RSpecでテストする方法
これはそれに対する良い答えです (そしてその理由): Testing named scopes with RSpec .
オプション #2: インスタンス上でアクションを実行する
MyClass#some_action
本当にインスタンス メソッドとして定義したいとしましょう。次に、これを試すことができます:
class MyClass < ActiveRecord::Base
scope :active, where(status: 'active')
scope :inactive, where(status: 'inactive')
def some_action
self.foo = 'bar'
self
end
end
この場合、配列全体ではなくインスタンスを返すMyClass.active.last.some_action
ため、 で実行できます。#last
some_action
RSpecでテストする方法
期待してテストするだけでいいと思います:
MyClass.should_receive(:some_action).at_least(:once)
MyClass.active.last.some_action
これに関する追加の議論: How to say any_instance should_receive any number in RSpec
オプション #3: 集団行動
本当に実行したいとしましょうMyClass.active.some_action
。最初にこれを試すことをお勧めします (オプション #2 と同じ例):
class MyClass < ActiveRecord::Base
scope :active, where(status: 'active')
scope :inactive, where(status: 'inactive')
def some_action
self.foo = 'bar'
self
end
end
そして、で実行しMyClass.active.all.map{|my_class| my_class.some_action }
ます。
ここで、本当に実装したい場合MyClass.active.some_action
-- some_action
ActiveRecord::Relation のすべてのインスタンスに対して実行したい場合 (これはお勧めしません)、次のようにします。
class MyClass < ActiveRecord::Base
scope :active, where(status: 'active')
scope :inactive, where(status: 'inactive')
def some_action
# really do it
end
end
と...
class ActiveRecord::Relation
# run some_action over all instances
def some_action
to_a.each {|object| object.some_action }.tap { reset }
end
end
繰り返しますが、これを行うことはお勧めしません。
some_action
RSpecでテストする方法
オプション #2 と同じケース:
MyClass.should_receive(:some_action).at_least(:once)
MyClass.active.last.some_action
注: すべてのコードは Ruby 2.0.0-p0 を使用しています。インストールして使ってみて、楽しい!:-)