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
результат
когда я построил проект, подобный этому,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 опций.