【问题标题】:Model associations using DataMapper in separate files在单独的文件中使用 DataMapper 进行模型关联
【发布时间】:2011-05-03 16:25:11
【问题描述】:

我正在使用 DataMapper 并尝试使用模型 Project 和 Task 之间的关联。我将模型放在单独的文件 project.rb 和 task.rb 中。当我尝试将它们相互关联时,出现以下错误:

Cannot find the parent_model Project for Task in project (NameError)

我认为这是由需要 task.rb 的 project.rb 引起的,反之亦然,因为如果我只是将它包含在其中一个文件中,该关联就可以正常工作。代码如下:

项目.rb

require 'dmconfig'
require 'task'

class Project
  include DataMapper::Resource
  property :id,         Serial
  has n,                :tasks
end

DataMapper.auto_upgrade!
DataMapper.finalize

task.rb

require 'dmconfig'
require 'project'

class Task
  include DataMapper::Resource
  property :id,         Serial
  belongs_to            :project
end

DataMapper.auto_upgrade!
DataMapper.finalize

dmconfig.rb

require 'rubygems'
require 'dm-core'
require 'dm-migrations'

DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, 'sqlite://' + Dir.pwd + '/taskmanager.db')

如果我从其中一个文件中删除关联,它可以正常工作,至少从一个方向:

require 'dmconfig'

class Project
  include DataMapper::Resource
  property :id,         Serial
end

DataMapper.auto_upgrade!
DataMapper.finalize

如果我希望关联从两个方向起作用,是否是将两个类放在同一个文件中的唯一合理解决方案?或者有什么方法可以让他们分开并仍然管理它?

【问题讨论】:

    标签: ruby associations datamapper


    【解决方案1】:

    您需要在需要所有您的模型之后调用finalize,而不是在每个模型之后。 finalize 所做的一件事是对您的模型进行健全性检查,以确保所有相关模型都已被要求。在需要所有库文件之后,应用程序启动过程是执行此操作的理想场所。我建议类似:

    项目.rb

    class Project
      include DataMapper::Resource
      property :id,         Serial
      has n,                :tasks
    end
    

    task.rb

    class Task
      include DataMapper::Resource
      property :id,         Serial
      belongs_to           :project
    end
    

    dmconfig.rb

    require 'dm-core'
    require 'dm-migrations'
    require 'project'
    require 'task'
    
    # note that at this point, all models are required!
    
    DataMapper::Logger.new($stdout, :debug)
    DataMapper.setup(:default, 'sqlite://' + Dir.pwd + '/taskmanager.db')
    DataMapper.finalize
    DataMapper.auto_upgrade!
    

    或者类似的东西。在您的应用程序中,您 require 'dmconfig' 并按照该要求进行了所有设置。 DataMapper 会在您调用 finalizeauto_upgrade! 之前推迟检查远端关系(例如,Task 模型中的项目),因此请确保在执行此操作之前需要所有模型。

    【讨论】:

      【解决方案2】:

      看起来这可能是由 task.rb 中的拼写错误引起的

        belongs_to,           :project
      

      应该写成:

      belongs_to :project
      

      就其价值而言,例如,在使用 Sinatra 时,我更喜欢将我的所有模型放在一个 lib/models.rb 文件中...至少在可管理的范围内。

      【讨论】:

      • 很好,但我的代码中没有那个错字。在帖子中修复它。
      【解决方案3】:

      首先,在调用 auto_upgrade 之前调用 DataMapper.finalize。其次,最好加载模型,调用 finalize 然后执行 DataMapper.auto_migrate!而不是在每个模型定义后调用 auto_upgrade。

      【讨论】:

      • require': stack level too deep (SystemStackError) from ./task.rb:1 from ./project.rb:2:in load' 来自 ./project.rb:2 来自 ./task.rb:2:in load' from ./task.rb:2 from ./project.rb:2:in load' 来自 ./project.rb:2 来自 ./task.rb :2:in `load' ... 8747 级...
      • 加载似乎给我带来了一个完全不同的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      相关资源
      最近更新 更多