railscast-study-2

#08 Layouts and content_for

content_for 用于定制网页特定的内容,

content_for 接受一个名称参数及代码块定义。代码块逻辑生成的内容将会被加载到布局文件中。

content_for 为我们提供在 Action 中定制布局文件定义的能力。诸如为某些指定的 Action 中增加用于显示菜单,滚动条等效果的 CSS 引用等。

1
2
3
4
5
6
7
8
9
10
<!-- projects/index.rhtml -->

<% content_for :head do %> <%= stylesheet_link_tag 'projects' %> <% end %>

<!-- layouts/application.rhtml -->

<head>
<title>Todo List</title>
<%= stylesheet_link_tag 'application' %> <%= yield :head %>
</head>

#10 11 12 Refactoring User Name

重构

把通用的逻辑抽取到一个工具方法中。

页面 view 中重复的逻辑,抽取到了 model 中。

需要重构的页面代码

1
2
3
4
5
6
7
8
9
10
11
<h1>Users</h1>
<ul>
<% for user in @users %>
<li>
<a href="<%= user_path(user) %>">
<%= user.first_name %> <%= "#{user.middle_initial}." unless
user.middle_initial.nil? %> <%= user.last_name %>
</a>
</li>
<% end %>
</ul>

资料页面

1
2
3
4
5
6
7
8
<h1>Profile</h1>
<p>
Name:
<%= @user.first_name %>
<%= "#{@user.middle_initial}." unless @user.middle_initial.nil? %>
<%= @user.last_name %>
</p>
<%= link_to 'Users List', users_path %>

两处代码中出现重复的内容,这时候就需要重构了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class User < ActiveRecord::Base
def full_name
name = first_name + ' '
name += "#{middle_initial}. " unless middle_initial.nil?
name += last_name
name
end
end

<h1>Users</h1>
<ul>
<% for user in @users %>
<li><%= link_to user.full_name %></li>
<% end %>
</ul>

标签的都用 link_to.

用测试来保障重构。

ruby 有 ruby 的编程方法,和 c 系语言完全不同,区别的根源就是迭代器的使用。

1
2
3
4
5
6
7
8
9
10

class User < ActiveRecord::Base
def full_name
[first_name, middle_initial_with_full_stop, last_name].compact.join(' ')
end

def middle_initial_with_full_stop
"#{middle_initial}." unless middle_initial.blank?
end
end