gpt4 book ai didi

ruby-on-rails - 将多输入虚拟属性移动到 SimpleForm 自定义输入组件

转载 作者:行者123 更新时间:2023-12-03 23:53:34 25 4
gpt4 key购买 nike

高度以英寸为单位存储在数据库中。

然而,英尺和英寸需要自己单独的输入形式:

Height: [_______] feet [_______] inches

所以我使用了虚拟属性,并让它工作。这是我的模型的简化版本:
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

_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 %>

这有效。但这并不理想。

我想把它弄干并创建一个 custom input component所以我可以用 <%= 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

形式。请注意,我没有放 <li>自定义输入中的标签,我认为这种方式更灵活,但可以随意更改。
# app/views/clients/_form.html.erb
<li>
<%= f.input :height, as: :feet_and_inch %>
</li>

所有这一切都依赖于这样一个事实:对于每个 height属性,你还有 height_feetheight_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

它基本上是一样的,但动态定义了方法。您可以在顶部看到您希望为其生成这些方法的属性列表。

请注意,所有这些都没有经过彻底的测试,可能会杀死你的猫,但希望能给你一些想法。

关于ruby-on-rails - 将多输入虚拟属性移动到 SimpleForm 自定义输入组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13792318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com