2017-02-14 10 views
-2

私はRailsのActiveRecordに関する質問があります。Rails ActiveRecord:メソッドを定義する場所は?

例えば、私はServiceモデルを持っていて、Servicenameという列を持っています。

これは

Service.class_method #=> 'This is class method' 

Service.find(1).instance_method #=> 'This is instance method' 

これは簡単で、その後app/model/service.rb

class Service < ActiveRecord::Base 

    def self.class_method 
    puts 'This is class method' 
    end 

    def instance_method 
    puts 'This is instance method' 
    end 
end 

私にできることです。しかし、私は、アレイ内のActiveRecordのインスタンスを取得するときに、例えば

Service.where(id: [1,2,3]) 

と私はどのように、どこでActive Recordのアレイのための方法を定義するために

Service.where(id: [1,2,3]).sample_method 

def sample_method 
    self.length 
end 

、などの方法がありますか?他のServiceクラスまたはインスタンスのようにこのオブジェクトを処理したいと思います。

ありがとうございました。

+0

...ほとんど常にあります。 –

答えて

0

まず、::関係のオブジェクトではなく、アレイ。配列と似たような振る舞いをしますが、データベースを照会するためにデータを処理/ SQLを構築するためのより多くのメソッドを継承します。

あなたはActiveRecordの::関連クラスに追加機能を追加したい場合は、あなたがこのような何かを行うことができます。

class ActiveRecord::Relation 
    def your_method 
    # do something 
    end 
end 

これは、libディレクトリや設定/初期化子として、どこか意味のある存在する必要があります。 。

これは、あなたが同様のハッシュ、またはArrayクラスのように、任意のRubyのクラスに似た何かを行うことができます

Service.where(id: [1,2,3]).your_method 

ような何かをできるようにする必要があります。

しかし、Railsの/ Rubyのソースクラスをオーバーライド/拡張​​より良い解決策は、あまりにも最初の段落を更新し

+0

ああ、私は誤解しました。 yes、 'where'は配列ではなくActiveRecord :: Relationオブジェクトを返します。したがって、最善の方法は、ActiveRecord :: Relationクラスを継承し、インスタンスメソッドを追加することです。ありがとう。 –

+0

あなたはそうすることができますが、一般的に言えば、ActiveRecord :: Relationクラスにメソッドを追加するのが最善の方法ではありません。私は個人的に別のクラスまたはモジュールを作成し、Service.where(id:[1,2,3])の結果を渡します。その後、ActiveRecord :: Relationの動作を変更することなく、そのクラスで行う必要がある操作を実行できます。これは、特定の機能を単独でテストすることができ、アプリケーションの他の領域でRelationクラスの在庫動作を変更する危険性がないため、より良い方法です。 – JayJay

0

だけでないのはなぜget_countget_nameのようなあなたの方法は...少し無意味です:

countよう
Service.count 

Service.find(1).name 

クラスメソッド、およびname(つまり、データベースのカラム名)のようなインスタンスメソッドは、すべての公共です - 独自のゲッターメソッドを定義する必要はありません。

あなたの第二の例として、あなただけで以下のように書くことができます:

Service.where(id: [1,2,3]).map{ |s| s.name } 

または同等に:それは計算を実行しているので

Service.where(id: [1,2,3]).map(&:name) 

しかし、以下では、実際にはより効率的ですではSQLではなく、ルビになります。 (あなたは私が何を意味するか混乱している場合は、両方のバージョンを実行してみて、ログに、SQLが生成されたものを比較する):ActiveRecordのを返すwhereすべての

Service.where(id: [1,2,3]).pluck(:name) 
+0

あいまいな質問を申し訳ありません。Active Record Arrayインスタンスのメソッドを定義する方法と場所を知りたいだけでした。誤解を避けるためにコードを少し変更します。 –

+0

私の答えはまだほとんど変わっていません...私は 'Service.where(id:[1,2,3])。map(&:length)'と書くだけです。 *これを 'def self.sample_method ....'と単純に定義することもできますが、オリジナルの質問と更新された質問のどちらにおいても合理的なユースケースを提供していません。 –

関連する問題