В моем приложении Rails I Pages, Blocks, BlockContents, Fields и FieldContents.Сохранение динамических полей в Rails
Ассоциации являются:
class Page < ActiveRecord::Base
has_many :blocks
has_many :block_contents, :through => :blocks
end
class Block < ActiveRecord::Base
belongs_to :page
has_many :block_contents
end
class BlockContent < ActiveRecord::Base
belongs_to :block
has_many :field_contents
end
class Field < ActiveRecord::Base
has_many :field_contents
end
class FieldContent < ActiveRecord::Base
belongs_to :block_content
belongs_to :field
validates :content, presence: true
end
Используя это, я могу иметь динамические поля для страницы.
Однако запись в БД в настоящее время осуществляется в контроллере так:
def update
@page = Page.find(params[:id])
if params[:field_content].present?
params[:field_content].each do |block_content|
block_content.last.each do |field|
field_content_row = FieldContent.where(block_content_id: block_content.first, field_id: field.first).first
if field_content_row.present?
field_content_row.update(content: field.last)
else
field_content = FieldContent.new
field_content.block_content_id = block_content.first
field_content.field_id = field.first
field_content.content = field.last
field_content.save
end
end
end
end
if @page.update_attributes(page_params)
redirect_to pages_path
else
render 'edit'
end
end
В то время как это делает в работе, это довольно грязная и не показывать мои валидаций для моего FieldContent в представлении (проверки выполняются, поскольку они не сохраняют полевой элемент, если они недействительны, но это должно препятствовать сохранению всей страницы и отображать ее в представлении).
Как я могу сделать это так, чтобы показывать подтверждение для FieldContent?
Для тех, кто хочет увидеть вид:
<% @page.blocks.each do |block| %>
<% block.block_contents.each do |block_content| %>
<% field_group.fields.each do |field| %>
<input name="field_content[<%= block_content.id %>][<%= field.id %>]" id="field_content_<%= block_content.id %>_<%= field.id %>" type="text" value="<%= get_field_content(block_content, field.name) %>">
<% end %>
<% end %>
<% end %>
и помощника я использую, чтобы получить содержание:
def get_field_content(block_content, field)
content = ''
block_content.field_contents.each do |field_content|
if field_content.field.name == field && field_content.block_content_id == block_content.id
content = field_content.content
end
end
content
end
Я сделал что-то подобное в приложении 5 лет назад, которое все еще может быть полезно. Не стесняйтесь проверять другие части, но [соответствующий лакомый кусочек здесь] (https://github.com/coreyward/talent-releases/blob/master/app/concerns/response_form.rb) с контроллером, интегрирующим его [здесь ] (https: // GitHub.ком/coreyward/талант-релизы/BLOB/Master/приложение/контроллеры/releases_controller.rb # L149-L153). – coreyward
@coreyward Это выглядит интересно, но я довольно новичок в Ruby и Rails, вы могли бы дать ответ с более подробным объяснением того, что делает ваш код. Я предполагаю, что ваша проблема связана с вашими моделями, так что сохранение происходит одновременно на обеих моделях? – Cameron
@coreyward Я обновил свой пост, чтобы показать, как выглядит этот вид. – Cameron