我有 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:不明确的列名:目标:选择“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