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

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

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

数据库建模

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,null: false
      t.string :value
    end
  end
end

应用模型

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

控制器:

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

视图:

= 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?

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

解决方法

我更喜欢这样的东西:

楷模

post.rb

class Post < ActiveRecord::Base
  has_many :categorizations
  has_many :categories,through: :categorizations

  accepts_nested_attributes_for :categorizations,allow_destroy: true
  accepts_nested_attributes_for :categories
end

category.rb

class Category < ActiveRecord::Base
  has_many :categorizations
  has_many :posts,through: :categorizations
end

调节器

...
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])
end

def post_params
  params.require(:post).permit(:name,category_ids: [])
end
...

查看
我总是喜欢普通的.erb所以,
simple_form的帮助下.

<%= simple_form_for(@post) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :content -%>
    ...
  </div>

  <div class="form-inputs">
    <%= f.association :categories,as: :check_Boxes -%>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

您可以通过这种方式检查/取消选中状态并轻松干净地销毁.
另外,你可以添加

<%= f.simple_fields_for :category do |category_fields| %>
  <%= category_fields.input :name -%>
<% end %>

获取关联的嵌套字段,但不要忘记在执行此操作时将相关的参数添加到strong_params.

...
def post_params
  params.require(:post).permit(:name,category_attributes: [:name])
end
....

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...