1

我有 3 个相关模型:项目、任务和子任务。

项目有很多任务,任务有很多子任务。因此任务属于项目,子任务属于任务。

目前,项目和子任务之间没有直接联系。我想做一个(并且可以访问@some_project.subtasks 和@some_subtask.project 之类的东西)。我想不要将 project_id 字段添加到子任务迁移中,而是使用任务模型作为项目和子任务之间的一种“连接”(因为任务已经有 project_id 列和与子任务的 has_many 关系)。

我首先编写项目 has_many :subtasks, :through => :taskssubtask 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
4

4 回答 4

2

你的错误:

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')

是由于您编写范围的方式,而不是您创建关系的方式。它说在表格和表格target都有一列。taskssubtasks

像这样重写范围应该至少可以修复该错误:

# tasks targeted today
scope :tasks_targeted_today, where("tasks.target > ? AND tasks.target < ?", start_of_day, end_of_day)

# subtasks targeted today
scope :subtasks_targeted_today, where("subtasks.target > ? AND subtasks.target < ?", start_of_day, end_of_day)

当您在这样的连接中的多个表中具有相同的列名时,您需要指定约束适用于哪个表和列。

于 2012-06-24T10:52:19.723 回答
1

如果您需要通过其他表的 belongs_to-like 关系,则使用has_one. 它允许您through在其选项中指定。

于 2012-06-24T10:14:30.287 回答
0

尝试这样的事情也许

class Projects < ActiveRecord::Base
  has_many :tasks
  has_many :subtasks, :through => :tasks, :foreign_key => "project_id"
于 2012-06-24T09:57:49.067 回答
0

您不能:trough在 belongs_to 关联中使用。但是,您可以轻松定义祖父母:

class Subtask < ActiveRecord::Base
  belongs_to :task
...
  def project
    task.project
  end
...

“不明确的列名”错误需要更多信息来解决。你能附上你试过的范围吗?

于 2012-06-24T10:00:42.097 回答