Ruby on Rails:如何在 select_tag 中显示以前的值

Ruby on Rails: How to display previous values in select_tag

这是我关于 Whosebug 的第一个问题,我是 Rails 上 Ruby 的新手,所以如果我问错了问题,我真的很抱歉。

我的问题:我有两个 类(单词和类别),现在我尝试通过变量 syntactical_category 将几个类别分配给一个单词,为此我使用 select_tag.这很好用,当用户创建一个新词时,您可以在命令行的这段代码中看到:

Parameters: {
  "utf8"=>"✓", 
  "authenticity_token"=>"EwGk/QrOma4JGJhSBjAT6fW9BqvuCJCEPYgNC9i/okOuQZBbh1ArNEfvuHvDRwY0Q2tABYTc/b3n3tAIlQmJRg==", 
  "word"=>{
    "name_de"=>"This is a test", 
    "description_de"=>"Test Description", 
    "syntactical_category"=>"5721e7fa8cc4b3285c000004", 
    "semantical_categories_ids"=>["57921a358cc4b36e42000001"]
  }, 
  "locale"=>"de"
}

但是当用户随后尝试编辑一个词时,select_tag 会忽略数据库中的值,只显示所有潜在类别的第一个类别,并覆盖旧值,如果用户再次提交单词。这不是我想要的。

有人有解决这个问题的办法吗?
如果此信息对您有帮助,我正在使用 Ruby 2.2.3、RubyonRails 4.2.4 和 MongoDB 3.0.9、Mongoid 和 haml。

请在下面找到我的代码。

word.rb

class Word
  include Mongoid::Document
  include Mongoid::Attributes::Dynamic
  include MultiLanguageText

  belongs_to :syntactical_category, class_name: "Category", inverse_of: nil, :autosave => true
  has_and_belongs_to_many :semantical_categories, class_name: "Category", inverse_of: nil, :autosave => true
  field :name_de, type: String
  field :name_en, type: String
  field :description_de, type: String
  field :description_en, type: String
end

words_controller.rb

class WordsController < ApplicationController
  helper MultiLanguageText

  def index
    @word = Word.all
  end

  def show
    @word = Word.find(params[:id])
  end

  def new
    @word = Word.new
  end

  def create
    @word = Word.new(word_params)

    respond_to do |format|
      if @word.save
        format.html { redirect_to @word, notice: t("word_create_success") }
        format.json { render :index, status: :created, location: @word }
      else
        format.html { render :new }
        format.json { render json: @word.errors, status: :unprocessable_entity }
      end
    end
  end

  def edit
    @word = Word.find(params[:id])
  end

  def update
    @word = Word.find params[:id]
    @word.update_attributes(word_params)

    respond_to do |format|
      if @word.update(word_params)
        format.html { redirect_to @word, notice: t("word_update_success") }
        format.json { render :index, status: :ok, location: @word }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @word = Word.find(params[:id])
    @word.destroy
    flash[:notice] = t(:delete_confirmation)
    redirect_to words_path
  end

  def word_params
    allow = [:name_de, :name_en, :description_de, :description_en, :syntactical_category, {:semantical_categories_ids => []}]
    params.require(:word).permit(allow)
  end
end

words/_form.html.haml

= form_for @word do |w|
  .field
    .input-append
      = select_tag 'word[semantical_categories_ids][]', options_for_select(Category.where(category_type: 'semantic').where(:name_de.exists => true).collect{|c| [c.name_de, c.id]})

提前感谢您的帮助!

只需在 collection

之后传递 @word.semantical_categories_ids
= select_tag 'word[semantical_categories_ids][]', options_for_select(Category.where(category_type: 'semantic').where(:name_de.exists => true).collect{|c| [c.name_de, c.id]}, @word.semantical_categories_ids)

而且我认为它应该接受多个值。如果是,在末尾添加 multiple: true

我认为你有 multiple 个选择 select_tag 所以,你必须做以下

= select_tag 'word[semantical_categories_ids][]', options_for_select(YOUR_COLLECTION,ARRAY_OF_SELECTED_VALUES),{multiple: true}

注意:将 ,{multiple: true} 添加到您的 select_tag

我找到了解决问题的办法。我不确定这是否 "the way to do it" 但对我来说它工作正常。

  - @word['semantical_categories_ids'] = [''] if !@word['semantical_categories_ids'].is_a? Array
  - @word['semantical_categories_ids'].each do |entry|
    = select_tag 'word[semantical_categories_ids][]', options_for_select(Category.where(category_type: 'semantic').where(:name_de.exists => true).collect{|c| [c.name_de, c.id]}, entry)