In meiner Rails app ich Seiten, Blöcke, BlockContents, Felder und FieldContents.Speichern dynamische Felder in Rails
Die Verbände sind:
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
diese Verwendung Ich bin in der Lage dynamische Felder für Seite zu haben.
jedoch an die DB Schreiben wird zur Zeit in der Steuerung wie dies getan:
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
Während dies tut in Arbeit, es ist ziemlich schmutzig und es zeigt nicht meinen Validierungen für meinen FieldContent in der Ansicht (die Validierungen funktionieren, da sie den FieldContent nicht speichern, wenn sie ungültig sind, aber es sollte verhindern, dass die gesamte Seite gespeichert und in der Ansicht angezeigt wird.
Wie kann ich es so machen, dass ich die Validierungen für FieldContent zeigen können?
Für diejenigen, die die Ansicht sehen möchten:
<% @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 %>
und die Helfer Ich benutze den Inhalt zu erhalten:
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
Ich habe etwas ähnliches auf einer App vor 5 Jahren, die noch nützlich sein können. Fühlen Sie sich frei, die anderen Teile zu überprüfen, aber [die entsprechenden tidbit ist hier] (https://github.com/coreyward/talent-releases/blob/master/app/concerns/response_form.rb) mit dem Controller es die Integration [hier ] (https: // github.com/coreyward/Talent-Releases/Blob/Master/App/Controller/Releases_controller.rb # L149-L153). – coreyward
@coreyward Das sieht interessant aus, aber ich bin ziemlich neu bei Ruby and Rails. Könnten Sie eine Antwort geben, die mehr erklärt, was Ihr Code tut? Ich nehme an, dass es Ihre Bedenken sind, Ihre Modelle so zu verknüpfen, dass die Speicherung gleichzeitig bei beiden Modellen erfolgt. – Cameron
@coreyward Ich habe meinen Beitrag aktualisiert, um zu zeigen, wie die Ansicht auch aussieht. – Cameron