プロジェクト、タスク、サブタスクの 3 つの関連モデルがあります。
プロジェクトには多くのタスクがあり、タスクには多くのサブタスクがあります。したがって、タスクはプロジェクトに属し、サブタスクはタスクに属します。
現在、プロジェクトとサブタスクの間に直接的なつながりはありません。私はそれを作りたいです(そして@some_project.subtasks&@some_subtask.projectのようなものにアクセスできます)。project_id フィールドをサブタスクの移行に追加するのではなく、タスク モデルをプロジェクトとサブタスク間の一種の「接続」として使用することを考えました(タスクには既に project_id 列があり、サブタスクとの has_many 関係があるため)。
プロジェクト has_many :subtasks, :through => :tasksとsubtask belongs_to :projectを書くことから始めました。
プロジェクト モデルで subtasks メソッドを取得しましたが、@some_subtask.project と記述すると、常に nil になります。また、@some_project.subtasks でスコープを使用すると、常に「あいまいな列名」エラーが発生します。
これは、私が人間関係を間違っていたからだと思います。それらを正しく行う方法は?また、サブタスク移行ファイルに project_id フィールドを追加することがより良い解決策 (またはまったく異なるもの) である場合は、ぜひお知らせください。
編集:列名エラーを返すスコープは次のとおりです( lib/ フォルダーにあり、タスクおよびサブタスクモデルに含まれるモジュールです)
10 # SCOPING
11 def self.included(base)
12
13 today = Date.today
14 start_of_day = DateTime.new(today.year, today.month, today.day, 0, 0, 1)
15 end_of_day = DateTime.new(today.year, today.month, today.day+1, 0, 0, 0)
16
17 base.class_eval do
18 scope :not_targeted, where(:target => nil)
19 scope :targeted, where("target IS NOT ?", nil)
20 scope :targeted_today, where("target > ? AND target < ?", start_of_day, end_of_day)
21 scope :targeted_after_today, where("target > ?", end_of_day)
22 scope :overdue, where("target < ?", start_of_day)
23 end
24
25 end
プロジェクトコントローラーでこれらのような変数を定義しようとすると、これらはエラーを返します(47行目と51行目がエラーの原因です)。基本的に、適切なレコードを渡して返すためにこれらが必要です。
35 @project_tasks = @project.tasks
36 @project_subtasks = @project.subtasks
45 @today_tasks = @project_tasks.targeted_today
46 @today_subtasks = @project_subtasks.targeted_today
47 @today = @today_tasks + @today_subtasks
48
49 @after_today_tasks = @project_tasks.targeted_after_today
50 @after_today_subtasks = @project_subtasks.targeted_after_today
51 @after_today = @after_today_tasks + @after_today_subtasks
たとえば、これは47行目が返すエラーです...
SQLite3::SQLException: あいまいな列名: ターゲット: SELECT "subtasks".* FROM "subtasks" INNER JOIN "tasks" ON "subtasks"."task_id" = "tasks"."id" WHERE "tasks"."project_id" = 1 AND (ターゲット > '2012-06-24 00:00:01' AND ターゲット < '2012-06-25 00:00:00')
プロジェクトモデルは次のとおりです。
1 class Project < ActiveRecord::Base
2
3 # RELATIONSHIPS
4 has_many :synapses, :dependent => :destroy
5 has_many :users, :through => :synapses, :dependent => :nullify
6
7 has_many :tasks, :dependent => :destroy
8 has_many :subtasks, :through => :tasks, :dependent => :destroy
9 has_many :discussions, :as => :discussionable, :dependent => :destroy
10
11 #use this when you don't have callbacks
12 #has_many :tasks, :dependent => :delete_all
13
14 # VALIDATIONS
15 validates :name, :presence => true,
16 :length => { :maximum => 50 }
17
18 validates :description, :presence => true,
19 :length => { :maximum => 200, :minimum => 15 }
20
21 # ATTRIBUTE ASSIGNMENT
22 attr_accessible :name, :description
23
24 # CUSTOM METHODS
25 def belonging_project
26 self
27 end
28
29 end
タスクモデルは次のとおりです。
1 class Task < ActiveRecord::Base
2
3 include SharedModelCode
4 # has scoping and validate method
5
6 # RELATIONSHIPS
7 belongs_to :project
8
9 has_many :vesicles, :dependent => :destroy
10 has_many :users, :through => :vesicles, :dependent => :nullify
11
12 has_many :subtasks
13
14 has_many :discussions, :as => :discussionable, :dependent => :destroy
15
16 # VALIDATIONS
17 validates :project, :presence => true
18 validates :name, :presence => true,
19 :length => { :maximum => 50 }
20 validates :description, :presence => true,
21 :length => { :maximum => 200, :minimum => 15 }
22 validate :target_date_cannot_be_in_the_past
23
24 # ATTRIBUTE ASSIGNMENT
25 attr_accessible :name, :description, :target, :completed
26
27 # CUSTOM METHODS
28 def belonging_project
29 Project.find_by_id(self.project_id)
30 end
31
32 end
サブタスクモデルは次のとおりです。
1 class Subtask < ActiveRecord::Base
2
3 include SharedModelCode
4 # has scoping and validate method
5
6 # RELATIONSHIPS
7 belongs_to :task
8 belongs_to :project
9
10 has_many :subvesicles, :dependent => :destroy
11 has_many :users, :through => :subvesicles, :dependent => :nullify
12
13 has_many :discussions, :as => :discussionable, :dependent => :destroy
14
15 # VALIDATIONS
16 validates :name, :presence => true
17 validates :task, :presence => true,
18 :length => { :maximum => 200 }
19 validate :target_date_cannot_be_in_the_past
20
21 # ATTRIBUTE ASSIGNMENT
22 attr_accessible :name, :target, :completed
23
24 # CUSTOM METHODS
25 def belonging_project
26 task = Task.find_by_id(self.task_id)
27 Project.find_by_id(task.project_id)
28 end
29
30 end