Rails 4以类似于wordpress选项表的方式保存字段

ugu*_*ark 7 ruby-on-rails ruby-on-rails-4

我正在尝试实现以下方案.基本上我有2个型号

主题

  • 标题

选项

  • theme_id
  • 名称

在我的表单中,我试图让用户使用set options填充Options表,例如我的html.erb可能如下所示:

<%= form_for [:admin, @options],:class => 'form'  do |f| %>

<div class="form-group">
<%= f.label :option[:color] %>
<%= f.text_field :option[:color], :class => 'form-control' %>
</div>

<div class="form-group">
<%= f.label :option[:header_title] %>
<%= f.text_field :option[:header_title], :class => 'form-control' %>
</div>

<div class="form-group">
<%= f.label :option[:footer_copy] %>
<%= f.text_field :option[:footer_copy], :class => 'form-control' %>
</div>

<div class="form-group">
<%= f.submit :value => 'Update', :class => 'btn btn-primary' %>
</div>

<% end %>
Run Code Online (Sandbox Code Playgroud)

上面的场景将在options表中添加3行,每行都有相同的theme_id.

但我不确定用于控制器(获取和发布操作),模型和视图的语法

任何帮助将不胜感激!谢谢

编辑保存上面的表单示例时,它将在选项表中保存为3个单独的行,例如:

theme_id | 名字| 值

1 | "颜色"| "绿色"

1 | "header_title"| "主题标题就在这里"

1 | "footer_copy"| "lorem ipsum bla bla"

PGi*_*ill 2

您需要在客户端动态生成这些字段

class Theme < ActiveRecord::Base
  has_many :options

  accepts_nested_attributes_for :options, allow_destroy: true
end
Run Code Online (Sandbox Code Playgroud)


class Option < ActiveRecord::Base
  belongs_to :theme
end
Run Code Online (Sandbox Code Playgroud)


class ThemesController < ApplicationController
  def new
    @theme = Theme.new
    3.times { @theme.options.build }
  end

private
  def theme_params
    params.require(:theme).permit(:title, options_attributes: [:id, :name, :value, :_destroy])
  end
end
Run Code Online (Sandbox Code Playgroud)

在你的views/themes/_form.html.erb中添加

<%= form_for(@theme) do |f| %>
  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>

  <%= f.fields_for :options do |builder| %>
    <%= render 'option_fields', f: builder %>
  <% end %>

  <%= link_to_add_fields "Add", f, :options %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

创建一个新的部分视图/主题/_option_fields.html.erb

<fieldset>
  <%= f.select :name, [["Color", "color"], ["Header", "header_title"], ["Footer", "footer_copy"]] %>
  <%= f.text_field :value, placeholder: "Value" %>
  <%= f.hidden_field :_destroy %>

  <%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
Run Code Online (Sandbox Code Playgroud)

在你的 theme.coffee 文件中添加

$(document).on "ready page:load", ->
  $('form').on 'click', '.remove_fields', (event) ->
    $(this).prev('input[type=hidden]').val('1')
    $(this).closest('fieldset').hide()
    event.preventDefault()

  $('form').on 'click', '.add_fields', (event) ->
    time = new Date().getTime()
    regexp = new RegExp($(this).data('id'), 'g')
    $(this).before($(this).data('fields').replace(regexp, time))
    event.preventDefault()
Run Code Online (Sandbox Code Playgroud)

在application_helper.rb中添加

module ApplicationHelper
  def link_to_add_fields(name, f, association)
    new_object = f.object.send(association).klass.new
    id = new_object.object_id
    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      render(association.to_s.singularize + "_fields", f: builder)
    end
    link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
  end
end
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述