您的位置:首页 > 大数据 > 人工智能

Rails3入门之十一 建立一个多模型的form

2011-12-13 23:05 225 查看
你的blog还有一个功能是给博客加上tag。需要实现这个功能的话需要你在一个form中实现多个模型的交互。

rails支持嵌套的form。

为了实现这些,我们将添加每个post多个tag。当你新建post时候,可以有多个tag。

首先我们增加tag模型。

$ rails generate model tag name:string post:references


然后运行DB整合建立新表

$ rake db:migrate
现在需要编辑post.rb建立关系。告诉rails你想通过post建立标签tag。

class Post < ActiveRecord::Base
validates :name,  :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }

has_many :comments, :dependent => :destroy
has_many :tags

accepts_nested_attributes_for :tags, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end


:allow_destroy的意思是告诉rails显示一个remove的checkbox。

:reject_if表示将会阻止保存新的tags。如果没有任何属性的话。

我们编辑 views/posts/_form.html.erb 来处理一个tag模板

<% @post.tags.build %>
<%= form_for(@post) do |post_form| %>
<% if @post.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% @post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= post_form.label :name %><br />
<%= post_form.text_field :name %>
</div>
<div class="field">
<%= post_form.label :title %><br />
<%= post_form.text_field :title %>
</div>
<div class="field">
<%= post_form.label :content %><br />
<%= post_form.text_area :content %>
</div>
<h2>Tags</h2>
<%= render :partial => 'tags/form',
:locals => {:form => post_form} %>
<div class="actions">
<%= post_form.submit %>
</div>
<% end %>


你发现我们改了 form_for(@post) do |f|是为了代码理解更加

容易。

这个例子展示了render的另外一个选项,为了传递一个本地变量。

在这个例子中,我们想本地变量form代替post_form对象。

我们也在头上加了个@post.tags.build 。这个保证有一个新的

tag可以被用户添加name。如果你不新建一个tag,这个页面将不会

显示因为没有新的tag对象来创建。

现在在app/views/tags 目录下创建_form.html.erb 。

这个页面包含tag的form。

<%= form.fields_for :tags do |tag_form| %>
<div class="field">
<%= tag_form.label :name, 'Tag:' %>
<%= tag_form.text_field :name %>
</div>
<% unless tag_form.object.nil? || tag_form.object.new_record? %>
<div class="field">
<%= tag_form.label :_destroy, 'Remove:' %>
<%= tag_form.check_box :_destroy %>
</div>
<% end %>
<% end %>
最后我们编辑 app/views/posts/show.html.erb 来显示我们的tags。

<p class="notice"><%= notice %></p>

<p>
<b>Name:</b>
<%= @post.name %>
</p>

<p>
<b>Title:</b>
<%= @post.title %>
</p>

<p>
<b>Content:</b>
<%= @post.content %>
</p>

<p>
<b>Tags:</b>
<%= @post.tags.map { |t| t.name }.join(", ") %>
</p>

<h2>Comments</h2>
<%= render @post.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>

<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |


做完这些,你会发现你可以编辑一个post和tags在同一页面。

但是@post.tags.map { |t| t.name }.join(", ")这个方法是不好的。

我们可以新建一个helper方法来做这些,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: