将模型中的多个输入字段转换为模型中的一个整数属性

时间:2014-02-11 00:09:38

标签: ruby-on-rails forms model associations

我试图允许用户在同一表单的两个不同的下拉菜单中输入两个不同的东西,它会将一个整数存储到一个评论表中。

我希望用户能够在一个下拉列表中选择model_name,在另一个下拉菜单中选择manufacturer。结果将在表单中存储bat_id整数。 (告诉你用户选择的蝙蝠)

我看过几个关于约会和问题的问题。时间,但他们直接将值存储在模型中。我试图存储一个整数 - bat_id,以便bat_id直接将评论模型链接到蝙蝠模型。

我发现的例子很接近:

我现在的表格:

<%= form_for(@review) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field" align= "center">
    <h3>Select Brand</h3>
    <%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
    <h3>Select Bat</h3>
    <%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>
    <h3>What do you like about this bat?</h3>
    <%= f.text_area :pros, placeholder: "Enter what you like..." %>
    <h3>What do you not like about this bat?</h3>
    <%= f.text_area :cons, placeholder: "Enter what you don't like..." %></br>
  </div>
  <div align="center">
  <%= f.submit "Add Review", class: "btn btn-large btn-info" %>
  </div>
<% end %>

我正在提交review表并尝试将这两个提交到bat_id属性。

<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>

在我的蝙蝠模型中,我有:has_many :reviews&amp;在我的评论模型中,我有:belongs_to :bat

UPDATE:是否可以使用带有javascript和我的两个输入组合的隐藏字段来确定我的输出bat_id?

更新我将下拉代码更改为有效,以便我输入manufacturer_id&amp;两者都被选中时bat_id。但是我仍然认为有一种方法可以在我的review模型中存储一个值。我使用的javascript与this

非常相似

2 个答案:

答案 0 :(得分:0)

从用户界面的角度来看,这似乎已经破了......用户将能够关联任何模型年份和任何制造商的名称,即使该制造商没有生产该型号年份&amp;名。

假设你将介绍一些javascript来处理它,从rails的角度来看,你会得到两个不同的行为:bat_id字段在同一个表单中。我想你需要这个:

<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>

或者,您可以创建一个包含复合字段的下拉列表,如下所示:

<h3>Select Bat</h3>
<%= 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

答案 1 :(得分:0)

正如您在其他答案中所述,您不需要将manufacturer_id存储在您的评论模型中。

我建议您在“评论”模型中创建访问的Manufacturer选项,但仅用于过滤表单上的蝙蝠列表。

执行此操作的最佳方法可能是向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}] } %>

然后在更改Bat选择时使用一些javascript过滤Manufacturer选择。

不幸的是,你不能只将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: Ignoring non-existant attributes passed to create()