如何在Rails中的连接表中获取相关记录?

时间:2013-11-27 10:48:50

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord associations

在我的Rails应用程序中,我有people,可以有很多projects,反之亦然:

# app/models/person.rb
class Person < ActiveRecord::Base
  has_many :people_projects
  has_many :projects, :through => :people_projects
end

# app/models/people_project.rb
class PeopleProject < ActiveRecord::Base 
  belongs_to :person
  belongs_to :project 
end

# app/models/project.rb
class Project < ActiveRecord::Base
  has_many :people_projects
  has_many :people, :through => :people_projects

  def self.search(person_id)
    if person_id
      where("person_id = ?", person_id) # not working because no person_id column in projects table
    else
      scoped
    end
  end
end

如何在person_id的{​​{1}}视图中按index过滤项目,例如使用这样的网址:ProjectsController

我无法理解这一点。请帮忙!感谢...

2 个答案:

答案 0 :(得分:1)

您在项目表中不会有person_id,因为它具有has_many&lt;&gt; has_many关系。

简单@ person.projects将执行加入btw person_projects&amp; project表并返回相应的项目。

*我假设,current_user返回一个Person对象。*

此外,完成您的模型定义。他们每个人都应该列出他们与PeopleProjects的关系

class Person < ActiveRecord::Base
  has_many :people_projects
  has_many :projects, :through => :people_projects
end

class Project < ActiveRecord::Base
  has_many :people_projects
  has_many :people, :through => :people_projects
end

答案 1 :(得分:1)

PersonProject模型的关联定义不完整。您还需要has_many :people_projects定义。

# app/models/person.rb
class Person < ActiveRecord::Base
  has_many :people_projects # <-- This line
  has_many :projects, :through => :people_projects
end

# app/models/project.rb
class Project < ActiveRecord::Base
  has_many :people_projects # <-- This line
  has_many :people, :through => :people_projects
end

# app/models/people_project.rb
# This is defined correctly
class PeopleProject < ActiveRecord::Base
  belongs_to :person
  belongs_to :project
end

请参阅The has_many :through Association了解更多详情。

通过此定义,您将能够使用current_user.projects获取当前用户的所有项目,就像您在ProjectsController#index中已经完成的那样。

更新:

您可以在joins方法中使用includessearch并应用where条件。如下所示:

# app/models/project.rb
class Project < ActiveRecord::Base
  has_many :people_projects
  has_many :people, :through => :people_projects

  def self.search(person_id)
    if person_id
      includes([:people_projects, :people]).where("people.id = ?", person_id) 
    else
      scoped
    end
  end
end