Связи моделей с использованием DataMapper в отдельных файлах - PullRequest
4 голосов
/ 02 ноября 2010

Я работаю с DataMapper и пытаюсь использовать ассоциации между моделями Project и Task.У меня есть модели в отдельных файлах project.rb и task.rb.Когда я пытаюсь связать их друг с другом, я получаю следующую ошибку:

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

Я понимаю, что это вызвано project.rb, требующим task.rb и наоборот, так как связь работаетхорошо, если я просто включу его в один из файлов.Вот код:

project.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

Если я хочу, чтобы связь работалаявляется ли единственное разумное решение просто поместить оба класса в один файл?Или есть способ, которым я могу держать их отдельно и при этом управлять ими?

Ответы [ 3 ]

9 голосов
/ 03 ноября 2010

Вам нужно позвонить finalize после того, как вам потребуются все ваших моделей, а не после каждой. finalize выполняет проверку работоспособности ваших моделей, чтобы убедиться, что все соответствующие модели были необходимы. Процесс загрузки приложения, требующий все файлы библиотеки, является идеальным местом для этого. Я предлагаю что-то вроде:

project.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 откладывает проверку на дальний конец отношений (скажем, проекты в модели задач) до тех пор, пока вы не вызовете finalize или auto_upgrade!, поэтому перед выполнением этого убедитесь, что все модели требуются.

1 голос
/ 02 ноября 2010

Похоже, что это может быть вызвано опечаткой в ​​task.rb

  belongs_to,           :project

должен быть записан как:

belongs_to :project

И для чего стоит, используя Синатра,например, я предпочитаю хранить все мои модели вместе в одном файле lib/models.rb ... по крайней мере, до тех пор, пока это возможно.

0 голосов
/ 02 ноября 2010

Прежде всего, вызовите DataMapper.finalize, прежде чем вызывать auto_upgrade.Во-вторых, лучше загрузить модели, вызвать finalize, а затем выполнить DataMapper.auto_migrate!вместо вызова auto_upgrade после каждого определения модели.

...