Esp*_*pen 51 forms post ruby-on-rails
我想以一种形式编辑我的模特照片的多个项目.我不确定如何使用表单正确显示和POST这个,以及如何在控制器中的更新操作中收集项目.
这就是我要的:
<form>
<input name="photos[1][title]" value="Photo with id 1" />
<input name="photos[2][title]" value="Photo with id 2" />
<input name="photos[3][title]" value="Custom title" />
</form>
Run Code Online (Sandbox Code Playgroud)
参数只是一个例子,就像我上面所说:我不确定以这种形式发布这些值的最佳方法.
在控制器中我想要这样的东西:
@photos = Photo.find( params[photos] )
@photos.each do |photo|
photo.update_attributes!(params[:photos][photo] )
end
Run Code Online (Sandbox Code Playgroud)
mme*_*ell 76
在Rails 4中,就是这样
<%= form_tag photos_update_path do %>
<% @photos.each do |photo| %>
<%= fields_for "photos[]", photo do |pf| %>
<%= pf.text_field :caption %>
... other photo fields
Run Code Online (Sandbox Code Playgroud)
aus*_*ton 48
Rails不会帮助你做很多事情.它违反了标准视图约定,因此您必须在视图,控制器甚至路径中进行变通方法.这没什么好玩的.
处理多模型形式Rails方式的关键资源是Stephen Chu的params-foo系列,或者如果你在Rails 2.3上,请查看嵌套对象表单
如果您定义正在编辑的某种奇异资源(如Photoset),则会变得更加容易.Photoset可以是真实的,ActiveRecord类型的模型,或者它可以只是一个接受数据并抛出错误的外观,就像它是ActiveRecord模型一样.
现在你可以写一个像这样的视图表单:
<%= form_for :photoset do |f|%>
<% f.object.photos.each do |photo| %>
<%= f.fields_for photo do |photo_form| %>
<%= photo_form.text_field :caption %>
<%= photo_form.label :caption %>
<%= photo_form.file_field :attached %>
<% end %>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
您的模型应验证每个进入的儿童照片并汇总其错误.您可能想查看一篇关于如何在任何课程中包含Validations的好文章.它可能看起来像这样:
class Photoset
include ActiveRecord::Validations
attr_accessor :photos
validate :all_photos_okay
def all_photos_okay
photos.each do |photo|
errors.add photo.errors unless photo.valid?
end
end
def save
photos.all?(&:save)
end
def photos=(incoming_data)
incoming_data.each do |incoming|
if incoming.respond_to? :attributes
@photos << incoming unless @photos.include? incoming
else
if incoming[:id]
target = @photos.select { |t| t.id == incoming[:id] }
end
if target
target.attributes = incoming
else
@photos << Photo.new incoming
end
end
end
end
def photos
# your photo-find logic here
@photos || Photo.find :all
end
end
Run Code Online (Sandbox Code Playgroud)
通过使用Photoset的外观模型,您可以使控制器和视图逻辑简单明了,为专用模型保留最复杂的代码.这段代码可能不会开箱即用,但希望它会给你一些想法,并指出你正确的方向来解决你的问题.
mlt*_*tsy 19
Rails有办法做到这一点 - 我不知道它何时被引入,但它基本上在这里描述:http://guides.rubyonrails.org/form_helpers.html#using-form-helpers
在没有父对象的情况下,需要稍微改变配置,但这似乎是正确的(它与gamov的答案基本相同,但更清晰,并且不允许混入"新"记录"更新"记录):
<%= form_tag photos_update_path do %>
<% @photos.each do |photo| %>
<%= fields_for "photos[#{photo.id}]", photo do |pf| %>
<%= pf.text_field :caption %>
... [other fields]
<% end %>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
在你的控制器中,你最终会得到一个哈希值params[:photos],其中键是照片ID,值是属性哈希值.
小智 16
您可以使用"model name []"语法来表示多个对象.
在视图中,使用"photo []"作为模型名称.
<% form_for "photo[]", :url => photos_update_path do |f| %>
<% for @photo in @photos %>
<%= render :partial => "photo_form", :locals => {f => f} %>
<%= submit_tag "Save"%>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
这将填充输入字段,就像您描述的那样.
在您的控制器中,您可以进行批量更新.
def update
Photo.update(params[:photo].keys, params[:photo].values)
...
end
Run Code Online (Sandbox Code Playgroud)
事实上,正如Turadg所提到的,如果你在Glen的答案中混合新的和现有的记录,Rack(Rails 3.0.5)就会失败.您可以通过使fields_for手动工作来解决此问题:
<%= form_tag photos_update_path do %>
<% @photos.each_with_index do |photo,i| %>
<%= fields_for 'photos[#{i}]', photo do |pf| %>
<%= pf.hidden_field :id %>
... [other photo fields]
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
如果你问我,这是非常难看的,但这是我发现在混合新记录和现有记录时编辑多个记录的唯一方法.这里的技巧是,params散列不是拥有一个记录数组,而是获取一个哈希数组(用i,0,1,2等编号)和记录哈希中的id.Rails将相应地更新现有记录并创建新记录.
还有一点需要注意:您仍然需要单独处理控制器中的新记录和现有记录(检查是否:id.present?)
| 归档时间: |
|
| 查看次数: |
54692 次 |
| 最近记录: |