在text_area中形成has_many

时间:2013-12-11 18:39:19

标签: ruby-on-rails

我有以下情况:

订单有很多页面。我想让用户将一堆(20多个)URL(它是一个Page属性)粘贴到文档区域中。

现在我没有使用与Order对象关联的Form,因为如果URL位于文本区域内,我无法看到如何嵌套URL。

我在此之前已经看过类似的问题:Rails: Using a Textarea for :has_many relationship,但我没有看到如何编写视图和模型以便这样做。

所以,如果我有这个:

订购has_many页面

这样的形式:

<%= form_for @order do |f| %>
  <%= f.text_area :page_urls?? %> # This would let the user paste X URLs, which would be 
                                   # used to create X Pages associated with the Order.
<% end %>

2 个答案:

答案 0 :(得分:1)

您可以保留您拥有的观看代码:

<%= form_for @order do |f| %>
  <%= f.text_area :page_urls %>
  #other field and submit button
<% end %>

在您的模型中,您需要执行以下操作:

attr_accessor :page_urls

after_validation do
  if page_urls
    parse_page_urls.each do |url|
      pages.create(url: url)
    end
  end
end

def parse_page_urls
  #use regexp to extract urls from page_urls string and return an array of url strings
end

定义了访问者,以便您可以在form_builder中使用:page_urls。您可以在模型中轻松设置验证:page_urls也是如此。

验证订单后,它将根据从page_urls属性中提取的网址数创建页面对象。

您可以参考this获取使用regexp从字符串中提取网址的一些帮助。

希望有所帮助!

答案 1 :(得分:0)

这是nested form处理得最好的工作。它允许您从父模型中提交has_many关系模型的属性,就像您希望的那样。例如,来自其文档:

想象一下,你有一个拥有_many:tasks的项目模型。为了能够使用此gem,您需要将accepts_nested_attributes_for :tasks添加到Project模型中。如果希望允许销毁嵌套对象,则将:allow_destroy => true选项添加到该声明中。有关所有可用选项的详细信息,请参阅accepts_nested_attributes_for文档。

这将创建tasks_attributes=方法,因此您可能需要将其添加到attr_accessible数组(attr_accessible :tasks_attributes)。

然后使用nested_form_for辅助方法启用嵌套。

<%= nested_form_for @project do |f| %>

然后,您可以在表单构建器上结合link_to_add使用link_to_removefields_for辅助方法来动态添加/删除嵌套记录。

<%= f.fields_for :tasks do |task_form| %>
  <%= task_form.text_field :name %>
  <%= task_form.link_to_remove "Remove this task" %>
<% end %>
<%= f.link_to_add "Add a task", :tasks %>

回应你的评论:

为了做类似的事情,你需要在控制器中进行处理以分离URL,然后创建一个与Page对象相关联的新@order对象。不幸的是,如果没有后处理,就没有办法做到这一点,除非你在客户端用隐藏的输入做JS。