Rails 4如何使用其他text_field的复选框集合为表单建模

Mat*_*att 6 checkbox database-design ruby-on-rails models

首先让我先说这也可能是一个建模问题,我对模型建议持开放态度.

使用案例:我有一个表单,我需要允许用户选择其帖子类别的复选框.如果没有适合其帖子检查的类别,则其他类别将显示用户添加自定义类别的文本字段.这应该用于创建和更新嵌套模块

数据库建模

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.string :name, null: false
      t.timestamps null: false
    end

    reversible do |dir|
      dir.up {
        Category.create(name: 'Hats')
        Category.create(name: 'Shirts')
        Category.create(name: 'Pants')
        Category.create(name: 'Shoes')
        Category.create(name: 'Other')
      }
    end

    create_table :categorizations, id: false do |t|
      t.belongs_to :post, index: true, null: false
      t.belongs_to :category, index: true, null: false
      t.string :value
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

应用模型

class Post < ActiveRecord::Base
  has_many :categorizations
  accepts_nested_attributes_for :categorizations, allow_destroy: true
  has_many :categories, through: :categorizations
  accepts_nested_attributes_for :categories
end

class Category < ActiveRecord::Base
  has_many :posts
end
Run Code Online (Sandbox Code Playgroud)

控制器:

  def update

    if @post.update(post_params)
      flash.now[:success] = 'success'
    else
      flash.now[:alert] = @post.errors.full_messages.to_sentence
    end

    render :edit
  end

  private

  def set_post
    @post = Post.find(params[:id])
    (Category.all - @post.categories).each do |category|
      @post.categorizations.build(category: category)
    end
    @post.categorizations.to_a.sort_by! {|x| x.category.id }
  end

  def post_params
    params.require(:post).permit(:name, :description,
                                categorizations_attributes: [ :category_id, :value, :_destroy],
                                )
  end
Run Code Online (Sandbox Code Playgroud)

视图:

= f.fields_for :categorizations do |ff|
    = ff.check_box :_destroy, { checked: ff.object.persisted? }, '0', '1'
    = ff.label :_destroy, ff.object.category.name
    = ff.hidden_field :category_id
    = ff.text_field :value if ff.object.category.other?
Run Code Online (Sandbox Code Playgroud)

但是,通过上述解决方案,我在保存时继续运行以复制记录错误.不知道为什么会这样?有一个更好的方法吗?

fbe*_*ger 2

不要将另一个存储在您的模型中,也不要存储它的名称!如果您使用form_for的是posts,只需添加一个不相关的字段即可。

例如:f.text_field :other_nametext_field_tag :other_name

手动将您的Other选项添加到下拉列表中。

如果选择其他,您可以添加 JS 来隐藏和显示隐藏的文本字段。

在您的 posts_controller 中执行以下操作:

def create
  ...
  if params[:other_name]
    post.categories.create(name: param[:other_name])
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)