2015-09-06 4 views
1

У меня есть следующий минимальный пример DataMapper модель:Почему я не могу назвать self.save! внутри Ruby DataMapper после: создать обратный вызов?

# model.rb 
require 'data_mapper' 

class Job 
    include DataMapper::Resource 
    after :create, :create_id_based_data 

    property :id, Serial 
    property :magicNumber, String 

    def create_id_based_data 
    self.magicNumber = "#{self.id}_#{Random.rand()}" 
    self.save! 
    end 
end 

DataMapper.setup(:default, 'sqlite::memory:') 
DataMapper.auto_migrate! 

Если я запускаю код в IRB, «MagicNumber» не сохраняется в базе данных:

irb -r ./model.rb 
2.2.1 :001 > Job.all 
=> [] 
2.2.1 :002 > Job.create 
=> #<Job @id=1 @magicNumber="1_0.6245356525078689"> 
2.2.1 :003 > Job.all 
=> [#<Job @id=1 @magicNumber=nil>] 

Я понимаю, что DataMapper помешает a повторенный save вызов внутри обратного вызова save, но не должен ли быть вызван save внутри create после крючка? И даже если обычный вызов save не разрешен, не должен ли вызов save! обойти все обратные вызовы и, следовательно, быть допустимым?

+0

Я бег DataMapper v1.2.0 – winni2k

ответ

1

Глядя на this bug report, появляется механизм (run_once), который мешает петле save звонков по-прежнему в игре. Не ясно, если это ошибка или нет. Использование save_self дает поведение, которое вы хотите, за счет использования полупубличного API.

# model.rb       
require 'data_mapper' 

class Job 
    include DataMapper::Resource 
    after :create, :create_id_based_data 

    property :id, Serial 
    property :magicNumber, String 

    def create_id_based_data 
    self.magicNumber = "#{self.id}_#{Random.rand()}" 
    save_self(false) 
    end 
end 

DataMapper.setup(:default, 'sqlite::memory:') 
DataMapper.auto_migrate! 

Результат:

irb -r ./model.rb 
2.1.0 :001 > Job.all 
=> [] 
2.1.0 :002 > Job.create 
=> #<Job @id=1 @magicNumber="1_0.7816860975338344"> 
2.1.0 :003 > Job.all 
=> [#<Job @id=1 @magicNumber="1_0.7816860975338344">] 
2.1.0 :004 > 
+0

К сожалению, я думаю, что я запутался вашим последним предложением. Согласны ли вы со мной, или вы говорите, что 'save !' ведет себя так, как можно было бы ожидать? – winni2k

+0

Я согласен с вами. Я ожидаю, что 'create' изменит хранилище данных, которое оно есть. Я ожидаю, что вызов «save!» В обратном вызове также должен изменить хранилище данных. Я ввел вопрос в dm-sqlite-adpater на github.com, пока комментариев нет. –