我有一个没有嵌套模型的表单。
class UserProductsController
def new
@user_product = current_user.user_products.build
end
end
使用jquery / javascript我想在同一表单上添加和删除新的@user_product字段。这通常看起来如何:
<%= form_for(@user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= f.submit %>
<% end %>
我正努力实现:
<%= form_for(@user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
---New ID(New generated ID, could be any new number in the database)
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %> # ajax style, this link removes this product entirely
----ID 3----
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %>
-----Add link------
<%= Add Another Field %> # ajax style adding
<%= f.submit %>
<% end %>
请注意未预设的新ID和一个提交按钮,这样一来,用户就可以一次创建一个产品。我如何实现上述目标?
谢谢。
使用User.rb模型,你可以做詹姆斯所说的。这是我的表格。
<%= form_for(current_user, :url => user_products_path) do |f| %>
<%= f.error_messages %>
<%= f.fields_for :user_products do |builder| %>
<%= render "user_product_fields", :f => builder %>
<% end %>
<%= link_to_add_fields "Add a UserProduct", f, :user_products %>
<%= f.submit "Create" %>
<% end %>
_user_product_fields.html.erb
<div class="fields">
<%= f.label :product, "Product" %>
<%= f.text_field :product %>
<%= f.label :address, "Address" %>
<%= f.text_field :address %>
<%= f.label :price %>
<%= f.text_field :price %>
<%= link_to_remove_fields "remove", f %>
</div>
答案 0 :(得分:2)
正如其他人所建议的那样(有点无益),请使用嵌套表格。
您需要将表单基于current_user对象,并使用fields_for声明:user_products。您需要将表单的url设置为使用url_for回发到user_product控制器而不是用户控制器,您需要调整user_product控制器更新并创建操作以使用params [:user]而不是params [: user_product]
如果你正确配置了accepts_nested_attributes,那么一切都应该是好的。
顺便说一句,如果你按照这些railscast,你会发现添加新的javascript对Rails 3.x不起作用
你应该为你的助手使用这样的东西
module ApplicationHelper
def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
end
end
和你的application.js文件中的javascript类似的东西
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
function remove_fields(link) {
$(link).previous("input[type=hidden]").value = "1";
$(link).up(".fields").hide();
}
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g")
$(link).up().insert({
after: content.replace(regexp, new_id)
});
}
显然你的form_for需要重构为像这样的
<%= form_for(current_user, :url => user_product_path) do |f| %>
<!-- add your f.fields_for :user_products here, probably in a rendered partial -->
<%end%>
这应该足够使用rails cast来让你前进
答案 1 :(得分:1)
答案 2 :(得分:1)
您可以使用cocoon。