有许多通过关系没有经典连接表

时间:2012-06-24 09:50:51

标签: ruby-on-rails

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

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

现在项目和子任务之间没有直接连接。我想制作一个(并且可以访问像@ some_project.subtasks& @ some_subtask.project这样的东西)。我认为不会将project_id字段添加到子任务迁移,而是将任务模型用作某种连接'在项目和子任务之间(因为任务已经有了project_id列和与子任务的has_many关系)。

我开始编写项目has_many:subasks,:through => :tasks subtask belongs_to:project

我在项目模型上得到了子任务方法,但是当我写@ 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:模糊列名:target:SELECT   &#34;子任务&#34;。* FROM&#34;子任务&#34; INNER JOIN&#34;任务&#34;上   &#34;子任务&#34;&#34; TASK_ID&#34; =&#34;任务&#34;。&#34; id&#34;在哪里&#34;任务&#34;。&#34; project_id&#34; = 1 AND   (目标&gt;&#39; 2012-06-24 00:00:01&#39;和目标&lt;&#; 2012-06-25 00:00:00&#39;)

这是项目模型:

  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 个答案:

答案 0 :(得分:2)

您的错误:

  

SQLite3 :: SQLException:模糊列名:target:SELECT“subtasks”。* FROM“subasks”INNER JOIN“tasks”ON“subasks”。“task_id”=“tasks”。“id”WHERE“tasks”。 “project_id”= 1 AND(目标&gt;'2012-06-24 00:00:01'和目标&lt;'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)

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

答案 1 :(得分:1)

如果您需要通过其他表格进行类似关系,请使用has_one。它允许您在其选项中指定through

答案 2 :(得分:0)

尝试类似这样的事情

class Projects < ActiveRecord::Base
  has_many :tasks
  has_many :subtasks, :through => :tasks, :foreign_key => "project_id"

答案 3 :(得分:0)

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

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

'模糊列名'错误需要更多信息才能解决。你能附上你试过的范围吗?