2011-07-29 8 views
3

他の外部キーを使用してhas_many関係の内容をフィルタリングするために好んだ方法を共有できるかどうかは疑問でした。たとえば、Departments、Employees、Projectsの3つのエンティティがあるとします。部署には従業員数が多く、プロジェクトには従業員数が多い。私はプロジェクトを持っています。私は与えられた部署から従業員全員を募集したいと思います。私のコードは次のようになります。Rails:他の外部キーとのhas_many関係

アプローチ1:クラスのクエリメソッド:

# anywhere.rb 

Employee.where(:project_id => project, :department_id => department) 

アプローチ2:ヘルパーメソッド

# department.rb 

has_many :employees 

# employee.rb 

belongs_to :department 
belongs_to :projects 

# project.rb 

has_many :employees 

今、私は私の問題への4つのアプローチを考えることができます

# project.rb 

def employees_from_department(department) 
    employees.select { |emp| emp.department == department } 
end 

APPROACH 3:関係のヘルパーメソッド

# project.rb 

has_many :employees do 
    def from_department(department) 
    where(:department_id => department) 
    # Could also be all.select { |emp| emp.department == deparment } 
    end 
end 

アプローチ4:スコープ

# employee.rb 

scope :from_department, lambda { |department| 
    where(:department_id => department) 
} 

# anywhere.rb 

project.employees.from_department(department) 

それが最も再使用可能なので、私はほとんど常に、アプローチ#4を選択してください。このスコープは、Employeesを返すクエリに適用できます。私はそれを他のスコープと組み合わせたり、順序を設定したりすることができます。スコープを使用すると、読み取り専用のすべてのクエリスタイルコードがかなり一貫して名前が付けられ、一番上に整理されます。スコープは、私の好きなRailsの機能の1つです。しかし、私は自分自身/すべての時間/を書いていることを知っているので、私は、belongs_toにマッチするようにパラメータ化されたスコープをほとんど持っています。それは正しいアプローチですか?また、私は大量のデータベースクエリを生成しているようですので、Railsが毎回データベースに行くように強制しているため、Railsが私にしてくれたキャッシュを破っているのだろうかと思います。

これはパフォーマンスに関する質問です。つまり、ワンサイズ対応の回答はなく、適切な方法を見つけるためには、実働環境でコードをテストする必要があります。しかし、コードが生産される前に、どのアプローチを選択する傾向がありますか?それとも別のことですか?

+0

#1(あなたが#3で 'all.select'を使用しない限り)、3位は同じSQLを生成する必要があります。 #4については、「プロジェクト」はどこですか? #2を使用しないと、余分なデータを取得し、 'employees.find(:all、:conditions => ...)'や '.find_by _...'やおそらく 'where'がこの場合にはるかに優れています。 –

+0

@Victor:スコープの使い方を示すため#4のコードを微調整しました。 –

答えて

2

私は個人的にスコープ(アプローチ4)またはクラスメソッドを好みます。

のように私はあなたが連鎖スコープを使用する場合は、通常の場合には、あなたのアプローチ4とアプローチ1は、同じSQL文を生成する必要があると考えてい

、:あなたは、コンソールにそれに.to_sql呼び出しを追加しようとすることができます

project.employees.from_department(department_id) 

生成された実際のSQLを確認します。

パフォーマンス(sql)分析では、query-reviewerまたはrack-bugなどのツールを使用すると便利で便利です。 (#3と基本的に同じ)

+0

私は#1と#4が同じSQLを生成することに同意します。 SQL解析ツールへのリンクありがとう! –

1
project.employees.find_by_department_id(department) 

関連する問題