Ответ 1
Насколько я знаю, вы не можете ничего переместить, кроме рендеринга на пользовательский ввод. SimpleForm не вызывается после отправки формы, поэтому он никак не может помешать значениям. Я хотел бы ошибаться в этом, поскольку мне это нужно и в прошлом. Во всяком случае, здесь версия, которая поддерживает логику преобразования в модели.
Пользовательский ввод SimpleForm:
# app/inputs/feet_and_inch_input.rb
class FeetAndInchInput < SimpleForm::Inputs::Base
def input
output = ""
label = @options.fetch(:label) { @attribute_name.to_s.capitalize }
feet_attribute = "#{attribute_name}_feet".to_sym
inches_attribute = "#{attribute_name}_inches".to_sym
output << @builder.input(feet_attribute, wrapper: false, label: label)
output << template.content_tag(:span, " feet ")
output << @builder.input(inches_attribute, wrapper: false, label: false)
output << template.content_tag(:span, " inches ")
output.html_safe
end
def label
""
end
end
Форма. Обратите внимание, что я не помещал теги <li>
внутри пользовательского ввода, я думаю, что он более гибкий, но не стесняйтесь его изменять.
# app/views/clients/_form.html.erb
<li>
<%= f.input :height, as: :feet_and_inch %>
</li>
Все это зависит от того, что для каждого атрибута height
у вас также есть атрибуты height_feet
и height_inches
.
Теперь для модели я не честно уверен, что если это так, может быть, кто-то может найти лучшее решение, НО вот он:
class Client < ActiveRecord::Base
attr_accessible :name
["height", "weight"].each do |attribute|
attr_accessible "#{attribute}_feet".to_sym
attr_accessible "#{attribute}_inches".to_sym
before_save do
feet = instance_variable_get("@#{attribute}_feet_ins_var").to_d
inches = instance_variable_get("@#{attribute}_inches_ins_var").to_d
self.send("#{attribute}=", feet*12 + inches)
end
define_method "#{attribute}_feet" do
value = self.send(attribute)
value.floor / 12 if value
end
define_method "#{attribute}_feet=" do |feet|
instance_variable_set("@#{attribute}_feet_ins_var", feet)
end
define_method "#{attribute}_inches=" do |inches|
instance_variable_set("@#{attribute}_inches_ins_var", inches)
end
define_method "#{attribute}_inches" do
value = self.send(attribute)
value % 12 if value && value % 12 != 0
end
end
end
В основном он делает то же самое, но определяет методы динамически. Вы можете увидеть вверху список атрибутов, для которых вы хотите, чтобы эти методы были сгенерированы.
Обратите внимание, что все это на самом деле не полностью проверено и может убить вашу кошку, но, надеюсь, может дать вам некоторые идеи.