boo*_*sey 13 ruby-on-rails simple-form
高度以英寸为单位存储在数据库中.
但是,英尺和英寸需要以下列形式输入:
Height: [_______] feet [_______] inches
Run Code Online (Sandbox Code Playgroud)
所以我使用了虚拟属性,并使其正常工作.这是我的模型的简化版本:
class Client < ActiveRecord::Base
attr_accessible :name, :height_feet, :height_inches
before_save :combine_height
def height_feet
height.floor/12 if height
end
def height_feet=(feet)
@feet = feet
end
def height_inches
if height && height%12 != 0
height%12
end
end
def height_inches=(inches) #on save?
@inches = inches
end
def combine_height
self.height = @feet.to_d*12 + @inches.to_d #if @feet.present?
end
end
Run Code Online (Sandbox Code Playgroud)
而_form部分使用simple_form:
<%= simple_form_for(@client) do |f| %>
<ul>
<%= f.error_notification %>
<%= f.input :name %>
<%= f.input :weight %>
<li>
<%= f.input :height_feet, :label => 'Height', :wrapper => false %>
<span>feet</span>
<%= f.input :height_inches, :label => false, :wrapper => false %>
<span>inches</span>
</li>
<%= f.error :base %>
</ul>
<%= f.button :submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
这有效.不过这是不理想的.
我想干这个并创建一个自定义输入组件,这样我就可以用<%= f.input :height, as: :feet_and_inch %>- 以及因此任何其他输入遵循相同模式的高度添加到表单中<%= f.input :wingspan, as: :feet_and_inch %>.
我已经尝试过自定义组件,但我无法获得两个输入显示 - 而且我不确定哪里是将'转换'逻辑从英尺和英寸放到英寸的最佳位置(同样从英寸返回到英尺和英寸).
据我所知,除了渲染到自定义输入之外,你无法真正移动任何东西.提交表单后不会调用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
Run Code Online (Sandbox Code Playgroud)
表格.请注意,我没有将<li>标签放在自定义输入中,我认为这样更灵活,但随时可以更改它.
# app/views/clients/_form.html.erb
<li>
<%= f.input :height, as: :feet_and_inch %>
</li>
Run Code Online (Sandbox Code Playgroud)
所有这一切都依赖于一个事实,对于每一个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
Run Code Online (Sandbox Code Playgroud)
它基本上是相同的,但动态定义方法.您可以在顶部看到您希望生成这些方法的属性列表.
请注意,所有这些都没有经过彻底的测试,可能会杀死你的猫,但希望可以给你一些想法.
| 归档时间: |
|
| 查看次数: |
1599 次 |
| 最近记录: |