在我的Rails应用程序I Pages,Blocks,BlockContents,Fields和FieldContents中.
协会是:
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
Run Code Online (Sandbox Code Playgroud)
使用这个,我可以为Page拥有动态字段.
但是,写入DB当前是在控制器中完成的,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
虽然这在工作中有用,但它很脏并且它没有在视图中显示我对FieldContent的验证(验证确实有效,因为如果它们无效则不保存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 %>
Run Code Online (Sandbox Code Playgroud)
和我用来获取内容的助手:
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
Run Code Online (Sandbox Code Playgroud)
首先,为了提交包含多个模型的表单,您首先需要做的是接受嵌套属性。
在 page.rb 文件中,输入:
class Page < ActiveRecord::Base
has_many :blocks
has_many :block_contents, :through => :blocks
accepts_nested_attributes_for :field_contents
Run Code Online (Sandbox Code Playgroud)
其次,在视图中 - 您必须使用“fields_for”指定哪些字段适用于哪个模型,因此在 form_for @page 中,您应该放置:
<%= f.fields_for :field_contents do |b| %>
Run Code Online (Sandbox Code Playgroud)
因为 :field_contents 是唯一会与 @page 一起更新的对象。因此整个表单元素看起来像这样:
<% @page.blocks.each do |block| %>
<% block.block_contents.each do |block_content| %>
<% field_group.fields.each do |field| %>
<%= form_for @page do |f| %>
<%= f.input :any attribute %>
<%= f.fields_for :field_contents do |b| %>
<%= b.text_field :content %>
<%= f.fields_for :block_contents do |b| %>
<%= b.hidden_field :block_content, value: "#{@block_content.id}"%>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
因为我了解到您已经可以访问 @page.field_content,所以您不必触摸控制器中的任何内容,因为它会根据现有关系自动更新记录。
现在我们已经在单个请求中提交了所有模型,您指定了希望在验证发生后在视图中显示错误消息。这是最简单的部分。
据我所知,您当前正在验证:content.
在你看来:只需放置一个HTML标签或rails内容标签
<p class= "error"><%= "Your error message"if @field_content.errors[:content].present? %></p>
Run Code Online (Sandbox Code Playgroud)
如果您还有任何疑问,请告诉我。
| 归档时间: |
|
| 查看次数: |
221 次 |
| 最近记录: |