Rails 4 сохранение полей аналогично таблице параметров wordpress

Я пытаюсь достичь следующего сценария. В основном у меня есть 2 модели

тема

  • заголовок

опции

  • theme_id
  • имя
  • стоимостью

в моей форме я пытаюсь позволить пользователю заполнить таблицу параметров параметрами set, например мой html.Эрб, возможно, будет выглядеть так:

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

приведенный выше сценарий добавит 3 строки в таблицу параметров, каждый с тем же theme_id.

но я не уверен в синтаксисе, который нужно использовать для контроллера (действия get и post), model и view

любая помощь будет оценена! Спасибо

изменить Когда приведенный выше пример формы будет сохранен, он сохранит как 3 отдельные строки в таблице параметров, например:

theme_id | name / value

1 | "Цвет" | "зеленые"

1 / "header_title" / "название темы идет здесь"

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

4 ответов


вам нужно динамически генерировать эти поля на стороне клиента

class Theme < ActiveRecord::Base
  has_many :options

  accepts_nested_attributes_for :options, allow_destroy: true
end


class Option < ActiveRecord::Base
  belongs_to :theme
end


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

в ваших представлениях / темах / _form.формат html.erb add

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

создайте новые частичные представления / темы / _option_fields.формат html.Эрб

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

в ваши темы.файл кофе добавить

$(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()

в application_helper.рубидий добавить

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

результат

enter image description here


когда я построил проект, подобный этому,Options имел свой собственный контроллер с функциональностью CRUD.

видео модели:

theme.rb

has_many :options

Модели

option.rb
belongs_to :video

Параметры Контроллера:

def create
@option = Option.new(option_params)
@video.theme_id = @theme.id
if @option.save
    ...
end

надеюсь, это полезно.


вы можете использовать fields_for с ресурсом, контроллером и представлением тем следующим образом:

# routes.rb
resources :themes

# app/controllers/themes_controller.rb
def new
  @theme = Theme.new
end

def create
 @theme = Theme.new theme_params
 @theme.save!

 [:color, :header_title, :footer_copy].each do |option_name|
   theme.options.create! name: option_name, value: params[:theme][option_name]
 end  
end

private
def theme_params
  params.require(:theme).permit(:title)
end

#app/views/themes/new.html.erb
<%= form_for @theme do |f| %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

  <% [:color, :header_title, :footer_copy].each do |option_name|
    <%= f.fields_for option_name do |option_form| %>
      <div>
        <%= option_form.label option_name %>
        <%= option_form.text_field option_name %>
      </div>  
    <% end %> 
  <% end %>
<% end %>

вы можете добавить проверку ошибок, стиль и т. д. выше, по мере необходимости.


используйте рельсы, встроенные в ассоциации и accepts_nested_attributes_for:

class Theme < ActiveRecord::Base
  has_many :options
  accepts_nested_attributes_for :options, reject_if: :all_blank, allow_destroy: true
end

class Option < ActiveRecord::Base
  belongs_to :theme
end

использовать кокон gem, чтобы избежать написания всего кода JS, примеры в HAML, но вы должны получить точку:

приложение.js

//= require cocoon

форма:

= form_for @theme do |f|
  .field
    = f.label :title
    %br
    = f.text_field :title
  %h3 Options
  #option
    = f.fields_for :options do |option|
      = render 'options_fields', f: option
    .links
      = link_to_add_association 'add option', f, :options
  = f.submit

_options_fields:

.nested-fields
  .field
    = f.label :name
    %br
    = f.text_field :name
  .field
    = f.label :value
    %br
    = f.text_field :value
  = link_to_remove_association "remove option", f

вопрос

вы хотите n полей (опций) или просто эти 3? кокон лучше подходит для добавление n опций.