Heeft veel door relatie zonder klassieke join-tafel

Ik heb 3 relevante modellen: project, taken en subtaken.

Project heeft veel taken en de taak heeft veel subtaken. Dienovereenkomstig behoort taak tot project en behoort subtaak tot de taak.

Right now there is no direct connection between project and subtasks. I would like to make one (and have access to things like @some_project.subtasks & @some_subtask.project). I thought to not add the project_id field to subtasks migration, but to use task model as a sort of 'connection' between projects and subtasks (since task already has project_id column and has_many relationship with subtasks).

I started by writing project has_many :subtasks, :through => :tasks and subtask belongs_to :project.

Ik kreeg de subtakenmethode op projectmodel, maar wanneer ik @ some_subtask.project schrijf, wordt ik altijd nihil. Ook als ik scoping gebruik op @ some_project.subtasks krijg ik altijd de foutmelding 'dubbelzinnige kolomnaam'.

Ik denk dat dit is omdat ik mijn relaties verkeerd heb gemaakt. Hoe goed te doen? Ook als het toevoegen van het veld project_id aan het migratiebestand van subtaketten de betere oplossing is (of iets geheel anders) laat het me dan zeker weten.

EDIT: hier zijn de bereiken die kolomnaamfout retourneren (ik heb ze in lib/folder, het is een module die is opgenomen in taak- en subtaskmodellen)

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

Those return error when I try to define variables like these in project controller (lines 47 and 51 are to blame for the error). Basically I need these to pass and return proper records.

 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

Dit is bijvoorbeeld de foutlijn 47 retourneert ...

SQLite3::SQLException: ambiguous column name: target: SELECT "subtasks".* FROM "subtasks" INNER JOIN "tasks" ON "subtasks"."task_id" = "tasks"."id" WHERE "tasks"."project_id" = 1 AND (target > '2012-06-24 00:00:01' AND target < '2012-06-25 00:00:00')

Hier is het projectmodel:

  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  

Hier is het taakmodel:

  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

Hier is het Subtask-model:

  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
1
Ok, ik heb de scopes en de foutmelding die het retourneert toegevoegd ...
toegevoegd de auteur oFca, de bron
Ter informatie: Rails breidt de tijd uit met methoden zoals all_xxx , waarbij xxx kan zijn: dag , week , maand , kwartaal , jaar . Het resultaat is een tijdbereik. Combineer het met de mogelijkheid van ActiveRecord om reeksen te verwerken en je krijgt de mogelijkheid om iets te doen als: .where (target: Time.now.all_day) .
toegevoegd de auteur jdoe, de bron
re de "dubbelzinnige kolom" -fout: Hoe ziet uw schema eruit? Voor zover ik kan vertellen zou @ project.subtasks prima moeten werken. Wat betreft @ subtask.project kunt u een project exemplaarmethode toevoegen aan Subtask: def project() task.project; end
toegevoegd de auteur Flambino, de bron

4 antwoord

Uw fout:

SQLite3::SQLException: ambiguous column name: target: SELECT "subtasks".* FROM "subtasks" INNER JOIN "tasks" ON "subtasks"."task_id" = "tasks"."id" WHERE "tasks"."project_id" = 1 AND (target > '2012-06-24 00:00:01' AND target < '2012-06-25 00:00:00')

is te danken aan hoe je je scopes hebt geschreven, niet hoe je je relaties hebt gecreëerd. Het zegt dat een kolom doel in beide de taken en subtaken tabellen.

Herschrijf dit bereik op zijn minst die fout:

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

Wanneer u dezelfde kolomnaam in meerdere tabellen in een join als deze hebt, moet u opgeven voor welke tabel en kolom de beperking geldt.

2
toegevoegd
je hebt het op de spijker! dank je. Dus als ik deze twee regels aan scopes toevoeg, krijg ik de lijst met alle taken en subtaken die zijn getarget (gepland) voor vandaag?
toegevoegd de auteur oFca, de bron
Ik geloof het wel - hoewel ik het niet zeker weet. Ik zou aanraden vooruit te gaan en vervolgens een nieuwe vraag te plaatsen als je vragen hebt nadat je wat verder bent gekomen. Succes!
toegevoegd de auteur Kevin Bedell, de bron

Als u de_ly-like-relatie wilt via een andere tabel, gebruik dan has_one . Hiermee kunt u tot opgeven in de opties.

1
toegevoegd
Bedankt werkte precies zoals ik wilde. Weet je wat ik moet doen om die scopes daar boven te krijgen?
toegevoegd de auteur oFca, de bron

U kunt : trog niet gebruiken in een___ behorende_to-koppeling. U kunt de grootouder echter eenvoudig definiëren:

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

De foutmelding 'dubbelzinnige kolomnaam' heeft meer informatie nodig om op te lossen. Kun je de scope die je hebt geprobeerd bevestigen?

0
toegevoegd
Ik heb de scopes bevestigd. Kun je alsjeblieft de code schrijven die je schreef, ik heb er moeite mee het te lezen ... bedankt
toegevoegd de auteur oFca, de bron

Probeer zoiets misschien

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