【发布时间】:2015-04-21 07:57:59
【问题描述】:
我目前无法找到一种对以下情况进行编码的好方法:
有一个Model叫做TcpService,它有两个属性port_from和port_to,都是整数。它还有一个名为portrange 的虚拟属性,它是一个字符串。 portrange 是属性port_from 和port_to 的字符串表示,所以portrange = "80 90" 应该产生port_from = 80、port_to = 90。我现在要做的是对creating 和updating 和TcpService-object 使用相同的Formtastic 表单。表格看起来很标准(HAML 代码):
= semantic_form_for @tcp_service do |f|
= f.inputs do
= f.input :portrange, as: :string, label: "Portrange"
-# calls @tcp_service.portrange to determine the shown value
= f.actions do
= f.action :submit, label: "Save"
问题是,我不知道有一种简单的方法可以让我想要的值出现在表单中。在new 上,我希望该字段为空,如果create 失败,我希望它显示错误的用户输入以及错误,否则使用portrange 填充port_from 和port_to。在edit 上,我希望出现port_from 和port_to 的字符串表示,如果update 失败,我希望它显示错误的用户输入以及错误,否则使用@ 填充port_from 和port_to 987654347@.
模型看起来像这样,这对我来说似乎很乱。 有没有更好的方法让它达到我的需要?
class TcpService < ActiveRecord::Base
# port_from, port_to: integer
attr_accessor :portrange
validate :portrange_to_ports # populates `port_from` and `port_to`
# using `portrange` AND adds errors
# raises exception if conversion fails
def self.string_to_ports(string)
... # do stuff
return port_from, port_to
end
# returns string representation of ports without touching self
def ports_to_string
... # do stuff
return string_representation
end
# is called every time portrange is set, namely during 'create' and 'update'
def portrange=(val)
return if val.nil?
@portrange = val
begin
self.port_from, self.port_to = TcpService.string_to_ports(val)
# catches conversion errors and makes errors of them
rescue StandardError => e
self.errors.add(:portrange, e.to_s())
end
end
# is called every time the form is rendered
def portrange
# if record is freshly loaded from DB, this is true
if self.port_from && self.port_to && @portrange.nil?
self.ports_to_string()
else
@portrange
end
end
private
# calls 'portrange=(val)' in order to add errors during validation
def portrange_to_ports
self.portrange = self.portrange
end
end
感谢阅读
【问题讨论】:
标签: ruby-on-rails validation formtastic