Я переношу проект с MongoMapper на Mongoid. У меня есть две модели, Graph
и Point
со ссылочным отношением 1-N, поэтому точка belongs_to :graph
и каждый график has_many :points
. Я переопределил инициализатор в модели Point, так как мне нужно сослаться на некоторое состояние из экземпляра графа, которому принадлежит точка, чтобы правильно инициализировать точку.
Однако кажется, что отношение не инициализируется даже после вызова super
в инициализаторе. Как правильно настроить состояние Пойнтов?
Вот упрощенная версия моих двух классов и инициализатора:
class Graph
include Mongoid::Document
has_many :points, dependent: :delete
field :type, type: String
field :timezone, type: String
# ...etc...
end
class Point
include Mongoid::Document
belongs_to :graph
field :date, type: Date
field :value, type: Float
field :urtext, type: String # as originally entered by user
field :nextday, type: Date
attr_accessible :urtext
validates :value, presence: true
validates :date, presence: true
def initialize(params, options={})
super(params, options)
parse_urtext
end
def parse_urtext(ur)
# for the sake of argument, imagine this is doing some critical calculation
# that requires info derived from current state of the graph at creation
# and which is related to parsing the urtext
self.date, self.value = urtext.split(",")
self.nextday = Time.use_zone(self.graph.timezone){ Time.zone.now.to_date + 1 }
end
end
Когда я пытаюсь создать новую точку, связанную с графиком, я получаю нулевую ошибку от инициализатора.
# in a console:
> g = Graph.first
> p = g.points.build( urtext: "2015-11-30,1" )
NoMethodError: undefined method `timezone' for nil:NilClass
from /rails_root/app/models/point.rb:34:in `parse_urtext'
from /rails_root/app/models/point.rb:22:in `initialize'
from /.../.rvm/gems/ruby-2.2.0/gems/mongoid-3.1.7/lib/mongoid/factory.rb:23:in `new'
...
Кто-нибудь может объяснить, почему это не работает? Я могу написать метод build_point для модели Graph и всегда создавать точки таким образом, но тогда я теряю преимущества следования соглашениям Rails. Обратные вызовы, похоже, тоже не дают мне желаемого поведения. (Проверки выполняются в первую очередь, и я хочу завершить инициализацию состояния перед проверками).
Рельсы 3.2.22, Монгоид 3.1.7