将模型中的多个输入字段转换为模型中的一个整数属性
我试图允许用户在同一表单的两个不同的下拉菜单中输入两个不同的东西,它会将一个整数存储到一个评论表中。
我希望用户能够在一个下拉列表中选择model_name
,在另一个下拉列表中选择manufacturer
。 结果将bat_id
整数存储到表单中。 (告诉你用户选择哪种蝙蝠)
我已经看到了几个关于日期和时间的问题,但是它们将值直接存储在模型中。 我试图存储一个整数 – bat_id
以便bat_id将审查模型直接链接到bat模型。
我发现的例子很接近:
- ruby on rails多参数属性如何真正起作用(datetime_select)
- 将多个字段Rails转换为一个模型属性
- 为一个属性使用多个输入字段
- Rails使用多个字段更新单个属性
我的表格现在:
Select Brand
Select Bat
What do you like about this bat?
What do you not like about this bat?
我正在提交review
表并尝试将这两个提交到bat_id
属性。
Select Brand
Select Bat
在我的蝙蝠模型中我有: has_many :reviews
&在我的评论模型中我有: belongs_to :bat
更新:是否可以使用javascript和我的两个输入组合的隐藏字段来确定我的一个输出bat_id?
更新我更改了我的下拉代码,以便在选中两者时输入manufacturer_id
和bat_id
。 但是我仍然认为有一种方法可以在我的review
模型中存储一个值。 我使用的javascript非常类似于此
从UI的角度来看,这似乎已经破碎……用户将能够将任何型号年份和名称与任何制造商相关联,即使该制造商未生产该型号年份和名称。
假设你将介绍一些javascript来处理它,从rails的角度来看,你会得到两个不同的行为:bat_id字段在同一个表单中。 我想你需要这个:
Select Brand
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %> Select Bat
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
或者,您可以创建一个包含复合字段的下拉列表,如下所示:
Select Bat
<%= f.collection_select :bat_id, Bat.all.sort {|a, b| a.manufacturer_model_year_and_name <=> b.manufacturer_model_year_and_name}, :id, :manufacturer_model_year_and_name, include_blank: true %>
然后在你的Bat模型中引入如下内容:
def manufacturer_model_year_and_name "#{self.manufacturer.name}: #{self.model_year_and_name}" end
如您在其他答案中所述,您不需要将manufacturer_id
存储在您的评论模型中。
我建议创建一个未在Review模型中访问的Manufacturer
选择,但仅用于过滤表单上的bat列表。
执行此操作的最佳方法可能是向Bat
选择添加一些自定义数据属性。
<%= collection_select :manufacturer, :manufacturer_id, Manufacturer.all, :id, :manufacturer %> <%= f.select :bat_id, Bat.all.map{ |b| [b.model_year_and_name, b.id, {'data-manufacturer' => b.manufacturer_id}] } %>
然后使用一些javascript来更改Manufacturer
选择更改时的Bat
选择。
不幸的是,你不能只将display: none
设置为一个选项元素来隐藏它。 这并不会隐藏许多浏览器中的选项。 因此,最好的方法是每次更改制造商选择时使用一些jQuery来克隆原始选择,并删除与所选制造商无关的任何选项。 像这样:
// rename the original select and hide it $('#bat_id').attr('id', 'bat_id_original').hide(); $('#manufacturer_id').on('change', function() { $('#bat_id').remove(); // remove any bat_id selects $bat = $('#bat_id_original') .clone() // clone the original .attr('id', 'bat_id') // change the ID to the proper id .insertAfter('#bat_id_original') // place it .show() // show it .find(':not(option[data-manufacturer="' + $(this).val() + '"])') .remove(); // find all options by other manufacturers and remove them });
您可能需要更改一些内容才能在安装中使用它,但您可以在jsFiddle上查看静态演示: http : //jsfiddle.net/JL6M5/
你可能需要拒绝表单提交上的manufacturer_id
字段,avitevet已经指出了这个应该有帮助的答案: Rails:忽略传递给create()的不存在的属性