首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多个关系时,rom-rb形成验证。

使用多个关系时,rom-rb形成验证。
EN

Stack Overflow用户
提问于 2015-07-19 19:56:53
回答 1查看 570关注 0票数 0

我正在尝试http://rom-rb.org/,但我想不出如何在多个源模型的存在下通过存在性验证。我希望下面的脚本可以保存一个新的活动和组织者,但是它说event_name不存在。

我遗漏了什么?

代码语言:javascript
复制
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:      'test@example.com',
  event_name: 'Test Event'
)

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-20 12:59:31

下面是您的脚本的更新版本,该版本工作如下:

代码语言:javascript
复制
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:      'test@example.com',
  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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31505336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档