【问题标题】:Pass values from select_tag in params从参数中的 select_tag 传递值
【发布时间】:2017-04-02 09:48:12
【问题描述】:

我创建了一个“select_tag”字段,当用户单击保存该字段的所有值以通过参数传递给控制器​​时,我需要它。问题是当我点击保存时,只有在这个字段中输入的第一个值被传递给控制器​​。

为了更好地理解,“select_tag”字段是通过另一个字段“f.text_field :members”字段填充的。当我单击“添加”按钮时,“f.text_field :members”字段的值将传递给“select_tag”字段,因此我希望能够从“select_tag”字段中检查所有这些值以进行验证和保存,我该怎么做?正如我已经说过的,只有输入的第一个值会被传递。

现在查看参数,我意识到作为“参数”返回的值只是在下拉列表中选择的值,不考虑其他值。如何传递下拉列表中的所有值?

代码:

<%= form_for(@focus_group) do |f| %>
  <% if @focus_group.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@focus_group.errors.count, "error") %> prohibited this focus_group from being saved:</h2>

      <ul>
      <% @focus_group.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <script type="text/javascript">
  $(function() {
    $('#focus_group_moderator, #focus_group_members').autocomplete({
      source: '/focus_groups/autocomplete.json'
    });
  });
  function add(){
    var value = $('#focus_group_members').val();
    var select = document.getElementById("membersAdded");
    var option = document.createElement("option");
    option.text = value;
    option.value = value;
    select.add(option);

    $('#focus_group_members').val("");
  }

  function removeFromSelect(){
    var select = document.getElementById("membersAdded");
    select.remove(select.selectedIndex);
  }
  </script>
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :topic %><br>
    <%= f.text_field :topic %>
  </div>
  <div class="field">
    <%= f.label :moderator %><br>
    <%= f.text_field :moderator %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
  <div class="field">
    <%= f.label :members %><br>
    <%= f.text_field :members %>
    <input onclick="add()" type="button" value="Add" /><br>
    <%= select_tag(:membersAdded, options_for_select([])) %>
    <input onclick="removeFromSelect()" type="button" value="Remove" /><br>
    <br>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

控制器

class FocusGroupsController < ApplicationController
  before_action :set_focus_group, only: [:show, :edit, :update, :destroy]
  include FocusGroupsHelper

  def index
    if(params[:term])
      @profile = Profile.all.select("name", "id")

      @lista = Array.new

      @profile.each do |x|
        @lista.push(x.name)
      end

      respond_to do |format|
        format.html
        format.json { render json: @lista.to_json}
      end
    else
      @focus_groups = FocusGroup.all
    end
  end

  def show
  end

  def new
    @focus_group = FocusGroup.new
    @membersAdded

    respond_to do |format|
      format.html
      format.json { render json: Profile.all.to_json}
    end
  end

  def edit
  end

  def create
    @moderator= find_profiles_id(focus_group_params[:moderator])
    @moderator.each do |f|
      @moderator_id = f.id
    end

    @params = focus_group_params
    @params[:moderator] = @moderator_id

    @focus_group = FocusGroup.new(@params)

    if @focus_group.save
      redirect_to @focus_group, notice: 'Focus group was successfully created.'
    else
      render :new
    end
  end

  def update
    if @focus_group.update(focus_group_params)
      redirect_to @focus_group, notice: 'Focus group was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @focus_group.destroy
    redirect_to focus_groups_url, notice: 'Focus group was successfully destroyed.'
  end

  def autocomplete
    if(params[:term])
      @profile = Profile.all.where("user_id <> 0 and is_template = 'f' and name LIKE ?", "#{params[:term]}%").select("name", "id")

      @lista = Array.new

      @profile.each do |x|
        @lista.push(x.name)
      end

      respond_to do |format|
        format.html
        format.json { render json: @lista.to_json}
      end
    end
  end

  def find_profiles_id(name)
    return Profile.all.where("name LIKE ?", "#{name}%").select("id")
  end

  def find_profiles_name(id)
    @profile = Profile.all.where("id = ?", "#{id}").select("name")

    @profile.each do |e|
      @name = e.name
    end
    return @name
  end

  private

    def set_focus_group
      @focus_group = FocusGroup.find(params[:id])
    end

    def focus_group_params
      params.require(:focus_group).permit(:name, :topic, :moderator, :description, :members, :membersAdded)
    end
end

【问题讨论】:

  • 发布您的控制器代码,包括您的 params 方法。 select-tag 字段是否在允许的参数列表中?
  • 编辑@toddmetheny
  • 现在查看参数,我意识到作为“参数”返回的值只是在下拉列表中选择的值,其他值不考虑。如何传递下拉列表中的所有值?
  • 你为什么要把它们放在选择框中?这样做的目的是什么?重点是只传递选定的值。否则为什么要使用选择框?
  • 我需要在下拉列表或任何内容中存储多个值,因此我将所有这些值传递给控制器​​。我使用 dd 只是为了在文本字段中“存储”所有需要的值,然后在控制器中使用它们。

标签: html ruby-on-rails validation ruby-on-rails-4


【解决方案1】:

有几种方法可以解决这个问题——但选择框本身在这种情况下没有任何意义。不提供任何实用程序。这是一种方法。您有单独的成员模型吗?看起来你实际上是在尝试做一个嵌套表单。如果您没有members 模型,请创建一个。单独创建一个焦点小组,并将成员表格放在焦点小组的展示页面上。一个焦点小组有许多成员,成员属于一个焦点小组(有一个焦点小组 id)。这将允许您说 @focus_group.members 并让所有成员回来。

如果您出于某种原因必须将它们添加到同一个表单中(我认为这不是最佳选择),您需要通过带有表单构建器的嵌套表单来执行此操作,该表单构建器允许您一次添加多个表单。你也可以创建一个服务对象,但这更复杂。

另一个我不太喜欢的选项是将所有成员推送到一个数组,然后在提交时将其作为参数传递。无需将成员添加到选择框中,您只需将它们推送到数组即可。然后,您将最终数组值设置为 members_added(或任何您命名的参数)。您需要在控制器中解压缩该数组以创建每个成员。我不喜欢这个。第一个选项是最干净的。我认为这是三者中第三好的方法。

【讨论】:

  • 我明白你的意思前两个选项我没有立即使用,因为我正在学习 Rails,同时我正在开发这个应用程序,因为我没有太多时间。我知道它不会达到最佳效果,但不要担心,因为它对这个软件没有商业用途。即使在这种情况下,第三种选择也是最好的选择,但我该怎么做呢?当我将这个数组放在一个字段中并通过参数将其步进到我的控制器时,你能做一个示例代码吗?提前感谢您的关注。
  • 哈哈——这是最糟糕的选择!第一个是最容易做到的,也是最好的!你会节省一些痛苦。但是,如果您想要第三个选项...您可以为members_added 创建一个hidden_field,然后每次单击添加时,获取该 hidden_​​field 中的值并更新数组。然后,当您提交时,所有这些值都会在您的隐藏字段中。
猜你喜欢
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2022-08-03
相关资源
最近更新 更多