RoR - 当自我的上下文在方法内部发生变化时,如何引用“旧的”自我对象

时间:2011-08-23 02:01:28

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

我的rails应用程序具有Podcast和Track模型。播客有许多曲目,曲目属于播客。

这是无聊的背景信息:

我们将音频文件上传到mixcloud。对于他们主持的每个节目,除了标准的html版本之外,它们还提供json表示。我们的应用程序获取并解析此json提要并使用返回的数据设置正在创建的Podcast对象的属性。

我们还可以使用Feed获取属于此Podcast的所有曲目的名称,然后在创建播客时在我们的数据库中创建这些曲目。

代码或多或少有效,但无法在任何新曲目上设置:podcast_id:

before_validation :create_tracks
def create_tracks
  # get json feed for podcast which is hosted hosted on mixcloud.com
  json = a_method_that_gets_and_parses_json(self.json_url)

  json.sections.each do |section|
    if section.section_type=="track"
      # track.name IS being set, but podcast_id is NOT being set, it is always null
      Track.create(:name=>section.track.name, :podcast_id=>self.id)
    end
  end             
end

我意识到问题是由于当我们在Track.create方法中使用它时 self 的上下文发生了变化。它不再像我们在self.json_url循环之外返回.each时那样引用播客。

因此,如果我不能在这里使用self,我如何将当前播客的id传递给Track.create方法?我已经尝试在方法的外部和内部设置变量,但似乎没有什么工作在这里。为了记录,正在创建轨道,正确设置它们的名称,只是我似乎无法设置的podcast_id。

1 个答案:

答案 0 :(得分:3)

self的背景在这里不会改变。它仍然是您拥有的Podcast对象。

问题是您正在调用此方法before_validation,该方法在保存对象之前发生,因此在给对象赋予id之前。您可能想要调用此after_create而不是before_validation,就像分配对象的ID一样。