2015-07-19 43 views
0

我正在尝试http://rom-rb.org/,并且无法弄清楚如何在存在多个源模型的情况下通过状态验证。我期望下面的脚本来保存一个新的事件和组织者,但它说event_name不存在。使用多个关系时的rom-rb表单验证

我错过了什么?

require 'bundler/inline' 

gemfile do 
    source 'https://rubygems.org' 
    gem 'rom' 
    gem 'rom-sql' 
    gem 'rom-rails' 
    gem 'activemodel' 
    gem 'sqlite3' 
    gem 'activesupport' 
end 

require 'rom' 
require 'rom-rails' 

`rm -Rf /tmp/romtest.sqlite` 
ROM.setup(:sql, 'sqlite:///tmp/romtest.sqlite') 

class Events < ROM::Relation[:sql] 
end 

class Organisers < ROM::Relation[:sql] 
end 

class CreateEvent < ROM::Commands::Create[:sql] 
    relation :events 
    register_as :create 
    result :one 

    associates :organiser, key: [:organiser_id, :id] 
end 

class CreateOrganiser < ROM::Commands::Create[:sql] 
    relation :organisers 
    register_as :create 
    result :one 
end 

class CreateEventWithOrganiser < ROM::Model::Form 
    commands organisers: :create, events: :create 

    input do 
    attribute :email 
    attribute :event_name 
    end 

    validations do 
    validates :event_name, presence: true 
    end 

    def commit! 
    command = organisers.create.with(
     email: email, 
    ) >> events.create.with(
     name: event_name, 
    ) 

    command.transaction do 
     command.call 
    end 
    end 
end 

ROM.finalize 
rom = ROM.env 
gateway = rom.gateways.fetch(:default) 
migration = gateway.migration do 
    change do 
    create_table :organisers do 
     primary_key :id 
     column :email, String, null: false 
    end 

    create_table :events do 
     primary_key :id 
     column :name, String, null: false 
     column :organiser_id, Integer, null: false 
    end 
    end 
end 

migration.apply(gateway.connection, :up) 

f = CreateEventWithOrganiser.build(
    email:  '[email protected]', 
    event_name: 'Test Event' 
) 

# Unexpectedly fails 
f.save 
puts f.errors.full_messages 
# => "Event name can't be blank" 
+0

我可以通过显式调用'验证,使这项工作;!除非成功,否则返回false,在'commit!'的顶部。这是预期的API? –

+0

从阅读源代码我也想'inject_commands_for:events,:organisers'而不是'commands organizers::create,events :::create',虽然这个方法没有出现在指南中。 –

回答

1

这是你的脚本的更新版本,其工作原理:

require 'rom' 
require 'rom-rails' 

`rm -Rf /tmp/romtest.sqlite` 
ROM.setup(:sql, 'sqlite:///tmp/romtest.sqlite') 

class Events < ROM::Relation[:sql] 
end 

class Organisers < ROM::Relation[:sql] 
end 

class CreateEvent < ROM::Commands::Create[:sql] 
    relation :events 
    register_as :create 
    result :one 

    associates :organiser, key: [:organiser_id, :id] 
end 

class CreateOrganiser < ROM::Commands::Create[:sql] 
    relation :organisers 
    register_as :create 
    result :one 
end 

class CreateEventWithOrganiser < ROM::Model::Form 
    inject_commands_for :organisers, :events 

    input do 
    attribute :email 
    attribute :event_name 
    end 

    validations do 
    validates :event_name, presence: true 
    end 

    def commit! 
    validate! 

    return if errors.any? 

    command = organisers.create.with(
     email: email 
    ) >> events.create.with(
     name: event_name 
    ) 

    command.transaction do 
     command.call 
    end 
    end 
end 

ROM.finalize 
rom = ROM.env 
gateway = rom.gateways.fetch(:default) 
migration = gateway.migration do 
    change do 
    create_table :organisers do 
     primary_key :id 
     column :email, String, null: false 
    end 

    create_table :events do 
     primary_key :id 
     column :name, String, null: false 
     column :organiser_id, Integer, null: false 
    end 
    end 
end 

migration.apply(gateway.connection, :up) 

f = CreateEventWithOrganiser.build(
    email:  '[email protected]', 
    event_name: 'Test Event' 
) 

puts f.save.result.inspect 
# #<ROM::Commands::Result::Success:0x007fa92b589ea0 @value={:id=>1, :name=>"Test Event", :organiser_id=>1}> 

为什么没有与commands工作的原因是因为这种方法会为你的表单的命令对象,并为提供验证每个命令只有在使用单个命令时才能正常工作。否则,每个命令都使用相同的验证器,这是没有意义的。当你使用inject_commands_for时,它会获取你自己的命令,而验证器没有设置,所以你可以自由地处理验证。

我认为我们应该停止在命令上设置验证器,这会使您的原始样本工作,但请注意您需要自己拨打validate!

我希望这会有所帮助。

我还创建展示如何做同样的无形式的要点是:https://gist.github.com/solnic/3b68342482cf1414f719

+0

谢谢!没有形式的例子真的帮助我理解事物如何融合在一起:) –