活动关系:通过关联检索记录?

时间:2011-09-08 22:56:11

标签: ruby-on-rails ruby-on-rails-3 activerecord active-relation

我有以下型号:

class User < ActiveRecord::Base
  has_many :survey_takings
end

class SurveyTaking < ActiveRecord::Base
  belongs_to :survey

  def self.surveys_taken # must return surveys, not survey_takings
    where(:state => 'completed').map(&:survey)
  end

  def self.last_survey_taken
    surveys_taken.maximum(:position) # that's Survey#position
  end
end

目标是能够从控制器调用@user.survey_takings.last_survey_taken。 (这是设计的,但是顺其自然;总的目标是能够在@user.survey_takings上调用可以在相关调查中使用关系的类方法。)

目前的形式,此代码不起作用;当我呼叫surveys_taken时,.map(&:survey)会将ActiveRelation折叠为数组。是否有某种方法可以为所有已加入的调查返回关系?我不能这样做:

def self.surveys_taken
  Survey.join(:survey_takings).where("survey_takings.state = 'completed'")
end

因为@user.survey_takings.surveys_taken会加入所有已完成的survey_takings,而不仅仅是@user已完成的survey_takings。

我想我想要的是等同于

class User < ActiveRecord::Base
  has_many :survey_takings
  has_many :surveys_taken, :through => :survey_takings, :source => :surveys
end

但我无法从SurveyTaking.last_survey_taken访问那个survey_taken关联。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您希望找到某个用户完成的调查?如果是这样,你可以这样做:

Survey.join(:survey_takings).where("survey_takings.state = 'completed'", :user => @user)

它看起来像而不是:

def self.surveys_taken
where(:state => 'completed').map(&:survey)
end

您可能想要使用范围:

scope :surveys_taken, where(:state => 'completed')

答案 1 :(得分:0)

我认为我正在寻找的是:

class SurveyTaking < ActiveRecord::Base
  def self.surveys_taken
    Survey.joins(:survey_takings).where("survey_takings.state = 'completed'").merge(self.scoped)
  end
end

这样,SurveyTaking.surveys_taken会返回任何人进行的调查,但@user.survey_takings.surveys_taken会返回@user进行的调查。关键是merge(self.scoped)

在接受之前等待进一步的评论..