2011-12-07 13 views
0

.. :)私が欲しいものコンプレックス団体あなたが見てみることができれば、この1に引っかかっ

は、特定のユーザーのすべての未完了のタスクを含むすべての未完成のプロジェクトを、得ることです。

これは私のセットアップは、これまでのところです:この設定は、プロジェクトのために働く

- for project in current_user.employee.unfinished_projects 

    = project.name 

    # THESE ARE NOT THE ONLY THE TASKS FOR THE CURRENT_USER 
    - for task in project.tasks (OR project.unfinished_tasks ?) 

     = task.name 

が、あります。私の見解(HAML)で

User (devise) 
    has_one :employee 

Employee 
    belongs_to :user 
    has_and_belongs_to_many :tasks 
    has_and_belongs_to_many :unfinished_tasks, :conditions => { :tasks => { :completed_at => nil } }, :class_name => "Task" 
    has_many :unfinished_projects, :through => :unfinished_tasks, :source => :project, :uniq => true (:include => :unfinished_tasks OR :include => :tasks ?) 

Project 
    has_many :tasks 

Task 
    belongs_to :project 
    has_and_belongs_to_many :employees 

私はこのような何かをしたいのですが未完成のタスクを持つプロジェクトのみ。

しかし、私はどのようにこれらのプロジェクトで未完成のタスクを含めるかわかりません。

誰もがこれを実行するための最善の方法を知っています。可能であれば、私はこのすべてのための単一のクエリを持っていたいと思います。

編集: 難しい部分は、タスクがcurrent_user用でなければならないということです。 プロジェクトは完全に読み込まれます。

しかし、それはタスクロードするとき:

- for task in project.tasks.unfinished 

をそれはこのない:それは何をすべき

Task Load (1.3ms) SELECT `tasks`.* FROM `tasks` WHERE `tasks`.`project_id` IN (12, 7, 13, 15, 14, 10, 16, 17, 9, 2, 3) 
Task Load (0.4ms) SELECT `tasks`.* FROM `tasks` WHERE `tasks`.`project_id` = 12 AND `tasks`.`completed_at` IS NULL 
Task Load (0.3ms) SELECT `tasks`.* FROM `tasks` WHERE `tasks`.`project_id` = 7 AND `tasks`.`completed_at` IS NULL 
Task Load (0.6ms) SELECT `tasks`.* FROM `tasks` WHERE `tasks`.`project_id` = 13 AND `tasks`.`completed_at` IS NULL 
etc. 

は、従業員の作業を取得することです:

べき
Employee 
    Projects 
    Tasks 

プロジェクトクエリーで結合されたインナーであったタスクです。

+0

あなたが求めていることは、明確ではありません。あなたは未完成のタスクを持っているプロジェクトのリストを "unfinished_projects"にしたいのですか?まだ完了していない(完了していない)プロジェクトに属しているタスクを意味するために「incomplete_tasks」を使用することを意味しますか? –

+0

未完成のプロジェクトは未完成のタスクが多いプロジェクトです。私は、特定の従業員からの未完成の課題を持つ未完成のプロジェクトをすべて欲しい。理想的には、これらのすべてのレコードが単一のクエリウィッチに含まれます。 –

+0

大きな問題は、プロジェクトを取得してプロジェクトのタスクをループした後で、もはやその特定の従業員に関連していないことです。 –

答えて

0

だから、これをやり直した後、私は本当に私の問題が何であるかは分かりませんでした。 私はスコープを使用しています。熱心な負荷のためのインクルードはスコープ内にあり、project.tasks自体のスコープはありません。

プロジェクトモデル:

has_many :tasks 
scope :assigned_to, lambda { |employee| { :include => { :tasks => :employees }, :conditions => { :tasks => { :employees => { :id => employee.id } } } } } 
scope :unfinished, :include => :tasks, :conditions => { :tasks => { :completed_at => nil } } 

ビュー:

- for project in Project.assigned_to(current_user.employee).unfinished 
    = project.name 
    - for task in project.tasks 
    = task.name 

が私にこの素敵なMySQLのクエリを提供します:魔法のように

SELECT `projects`.`id` AS t0_r0, `projects`.`name` AS t0_r1, `projects`.`description` AS t0_r2, `projects`.`completed_at` AS t0_r3, `projects`.`created_at` AS t0_r4, `projects`.`updated_at` AS t0_r5, `tasks`.`id` AS t1_r0, `tasks`.`name` AS t1_r1, `tasks`.`description` AS t1_r2, `tasks`.`estimated_duration` AS t1_r3, `tasks`.`calculated_duration` AS t1_r4, `tasks`.`status` AS t1_r5, `tasks`.`completed_at` AS t1_r6, `tasks`.`project_id` AS t1_r7, `tasks`.`created_at` AS t1_r8, `tasks`.`updated_at` AS t1_r9, `employees`.`id` AS t2_r0, `employees`.`alias` AS t2_r1, `employees`.`comments` AS t2_r2, `employees`.`user_id` AS t2_r3, `employees`.`created_at` AS t2_r4, `employees`.`updated_at` AS t2_r5 FROM `projects` LEFT OUTER JOIN `tasks` ON `tasks`.`project_id` = `projects`.`id` LEFT OUTER JOIN `employees_tasks` ON `employees_tasks`.`task_id` = `tasks`.`id` LEFT OUTER JOIN `employees` ON `employees`.`id` = `employees_tasks`.`employee_id` WHERE `employees`.`id` = 3 AND `tasks`.`completed_at` IS NULL 

作品!

Taryn ..に特別なお礼ありがとうございます;)

0

私の質問(上記)は、あなたが見たいと思うものの真の例であると仮定します。

これをカバーするにはnamed_scopesを使用できます。例えば

Task 
    named_scope :unfinished, :conditions => {:unfinished => true} 

または何でもそれは未完成だということを示すために使用される条件。次に、使用することができます:

- for task in project.tasks.unfinished 

"unfinished_projects"のnamed_scopeは似ていますが、やや複雑です。 それはあなたが使用するデータベースに依存するいくつかの裸のSQLを必要としますが、一般的にあなたがタスクに参加して、プロジェクトshtが未完成のタスクを1つ持っていることを要求します。

Project 
    named_scope :unfinished, 
    :joins => 'inner join tasks on tasks.project_id = projects.id', 
    :conditions => ['tasks.unfinished IS TRUE'] 

次に、上記のように、それを使用します:ユーザーだけのために未完了のタスクを持ってプロジェクトを見つける1については

- for project in current_user.employee.projects.unfinished 

私は、これはあなたが必要なものに近い来るかもしれない推測しています、あなたは例えばスコープにパラメータとしてユーザーを追加することができ、次のよう

Project 
    named_scope :unfinished_for_user, lambda {|the_user_id| 
    :joins => 'inner join tasks on tasks.project_id = projects.id', 
    :conditions => ['tasks.unfinished IS TRUE AND tasks.user_id = ?', the_user_id] 
    } 
+0

スコープを使用しようとしていますが、うまくいけばそれはもう少し明確になります。問題はProject.unfinishedスコープだけです。本当にそれを作成する方法を知りません。スコープ:未完了、:条件=> {:tasks => "completed_at' is not NULL"} –

+1

私はその仕事をしていることを含めるために私のコメントを更新しました。そのためのSQL。 "Project.all"で条件を試すだけでテストできます。 –

+0

私はRails3を使用していて、以下のスコープを作成しました: 'scope:unfinished、:include =>:tasks、:conditions =>' 'tasks.completed_at IS NOT NULL' "問題は今私はユニークなプロジェクトを取得していないということです。 –

0

をだから私の質問への答えは次のとおりです。

モデル:

Employee: 
    has_and_belongs_to_many :tasks 
    has_many :projects, :through => :tasks, :uniq => true 

Project: 
    has_many :tasks 
    scope :unfinished, :include => :tasks, :conditions => { :tasks => { :completed_at => nil } } 

Task: 
    scope :unfinished, :conditions => { :completed_at => nil } 
    scope :of_user, lambda { |user| { :include => :employees, :conditions => { :employees => { :id => user.employee.id } } } } 

ビュー:

- for project in current_user.employee.projects.unfinished 

    - for task in project.tasks.unfinished.of_user(current_user) 

私はそれは非常に迷惑Project.unfinishedはすでに不完全なタスクが含まれていることを見つけます。

なぜ私はこれらを再度取得する必要がありますか、私は各プロジェクトの新しいクエリを与えます!不必要な権利ですか?

+0

余分なSQLを削除するには、 "eager loading"を調べてください。 –

+0

私はそれが私の問題だと思っています。私は熱心な負荷にしたいと思いますが、私が試したすべてのことは仕事を邪魔します..私が熱心な負荷のためのタスクを含んでいれば、それらはユーザー固有のものではありません.. –

+0

hmmm ... named_scopeの指定されたタスクと一致するuser_idの要件を含めることができます。パラメータとして渡すこともできます...私は答えに例を追加します。 –

関連する問題