1. git checkout -b updating-users
2. in this chapter, we will make you can update user profile.
a. we will use a "edit" action to render a view to edit user.
b. we will use "update" action and a "PUT" request to update user profile
c. we need to make sure only current user can update their information. this need a "before_filter"
3. edit form, we will start from TDD again!!
describe UserController do describe "get 'edit'" do before(:each) do @user = Factory(:user) test_sign_in(@user) end it "should be success" do get :edit, :id => @user response.should be_success end it "should have the right title" do get :edit, :id => @user response.should have_selector("title", :content => "Edit user") end it "should have the link to gravatar" do get :edit, :id => @user gravatar_url = "http://gravatar.com/emails" response.should have_selector("a", :href => gravatar_url, :content => "change") end end end
4. now it is time to write the view code:
<h1>Edit User</h1> <%= form_for @user do |f| %> <%= render "shared/error_messages", :object => f.object %> <div class="field"> <%= f.label :name %> <br /> <%= f.text_field :name %> <br /> <%= f.label :email %> <br /> <%= f.text_field :email %> <br /> <%= f.label :password %> <br /> <%= f.password_field :password %> <br /> <%= f.label :password_confirmation, "Confirmation" %><br /> <%= f.password_field :password_confirmation %> <br /> </div> <div class="action"> <%= f.submit "Update"%> </div> <% end %> <div> <%= gravatar_for @user %> <a href="http://gravatar.com/emails">Change</a> </div>
you can find we passed a object param when rendering partial .
this is common because a real partial should not rely on the fact that there is a @user object.
this is especially useful when composing a form,
<%= render 'shared/error_messages', :object => f.object %>
this create a var called object in the partial,
now we need to re-write the _error_messages partial:
<% if object.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(object.errors.count, "error") %> prohibited this <%= object.class.to_s.underscore.humanize.downcase %> from being saved:</h2> <p>There were problems with the following fields:</p> <ul> <% object.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
we can learn two helper method here:
"ActiveRecord".underscore ======> active_record (lower case and add _ )
"active_record".humanize =======> Active record (capitalize, and replace _ with space.)
5. next, let's look at the html gened by the form:
<form action="/users/1" class="edit_user" id="edit_user_1" method="post"><input name="_method" type="hidden" value="put" />. . . </form>
note this hidden line:
since web browser can't natively send "PUT" request, rails fake it with a post request, and a hidden input field.
6. there is another magic that you may wondering,
we use the same code for edit form and new form, but why the html generated are different?
for new action, rails use a post method, and for edit action, rails use a put method.
the answer is simple and trikey, rails will run
@user.new_record?
to judge if this record is a new one, or already exist in database.
so rails will know to use a put request or post request, clever?? cool!
7. next is the test for update success and update failure.
describe "PUT 'update'" do before(:each) do @user = Factory(:user) test_sign_in(@user) end describe "update failure" do before(:each) do @attr = {:name => "", :email => "", :password => "", :password_confirmation => "" } end it "should render the edit page" do put :update, :id => @user, :user => @attr response.should render_template('edit') end it "should have the right title" do put :update, :id => @user, :user => @attr response.should have_selector("title", :content => "Edit user") end end describe "update success" do before(:each) do @attr = { :name => "New Name", :email => "user@example.org", :password => "barbaz", :password_confirmation => "barbaz" } end it "should redirect to user show page" do put :update, :id => @user, :user => @attr response.should redirect_to user_path(@user) end it "should change user's attrs" do put :update, :id => @user, :user => @attr @user.reload @user.name.should == @attr[:name] @user.email.should == @attr[:email] end it "should have a flash message" do put :update, :id => @user, :user => @attr flash[:success].should =~ /updated/i end end end
one thing to note:
@user.reload ========> this will reload the @user content from database.
8. next, we will implement the update method in the controller:
def update @user = User.find_by_id(params[:id]) if @user.update_attributes(params[:user]) flash[:success] = "Profile updated" redirect_to @user else @title = "Edit user" render 'edit' end end
发表评论
-
12.3.3 scaling issue of the status feed
2011-10-30 17:54 814the problem of the implementati ... -
12.3 the status feed
2011-10-30 15:34 8521. we need to get all the micro ... -
12.2 a working follow button with Ajax
2011-10-29 18:10 9091. in the last chapter, in the ... -
12.2 a web interface for following and followers.
2011-10-28 22:14 8751.before we do the UI, we need ... -
12. following user, 12.1 relationship model
2011-10-18 14:29 7471. we need to use a relationshi ... -
11.3 manipulating microposts.
2011-10-17 15:31 8931. since all micropost actions ... -
11.2 show microposts.
2011-10-17 12:01 6981. add test to test the new use ... -
11.1 user micropost -- a micropost model.
2011-10-17 10:43 11031. we will first generate a mic ... -
10.4 destroying users.
2011-10-16 15:47 733in this chapter, we will add de ... -
10.3 showing users list
2011-10-15 20:41 768in this chapter, we will do use ... -
10.2 protect pages.
2011-10-15 15:11 656again, we will start from TD ... -
9.4 sign out
2011-10-13 15:21 731whew!!!, last chapter is a long ... -
9.3 sign in success.
2011-10-12 15:39 7411. we will first finish the cre ... -
9.1 about flash.now[:error] vs flash[:error]
2011-10-12 15:37 722There’s a subtle difference ... -
9.2 sign in failure
2011-10-12 12:19 655start from TDD!!! 1. requir ... -
9.1 sessions
2011-10-12 10:00 643a session is a semi-permanent c ... -
what test framework should you use?
2011-10-11 16:56 0for integration test, i have no ... -
what test framework should you use?
2011-10-11 16:56 0<p>for integration test, ... -
8.4 rspec integration tests
2011-10-11 16:53 714in integration test, you can te ... -
8.3 sign up success
2011-10-11 14:39 776Chapter 8.3 this part, we will ...
相关推荐
针对“PATCH-Updating System.zip”这个压缩包文件,我们可以推断它包含了一个与Unity引擎相关的版本更新或补丁包,主要服务于PC平台。下面将详细讨论Unity引擎的版本更新、补丁管理和Unitypackage文件格式。 Unity...
MySQL数据库在运行过程中可能会遇到各种问题,其中一种常见的错误是"Starting MySQL.Manager of pid-file quit without updating file.[FAILED]"。这个错误通常表明MySQL服务在尝试启动时遇到了问题,导致进程管理器...
本资源"LeetCode of algorithms with golang solution(updating)",是用Go语言解决LeetCode算法问题的集合,持续更新,旨在帮助Go语言开发者提升算法能力,理解并运用到实际项目中。 Go语言,又称Golang,是由...
当使用PyCharm这个流行的Python集成开发环境时,有时会遇到一个问题,即IDE启动后会不断进行索引更新,表现为其界面上会出现"Updating indices"或"indexing"的信息,并且长时间处于该状态无法正常使用。这种情况不仅...
From retrieving data from single tables to creating and updating tables and views, this guide is a valuable resource for SAS users looking to leverage SQL within the SAS environment.
paper :artist_palette: paper 是一个简洁,没有过多冗余视觉元素和功能的 hexo 主题,其设计风格的灵感来源于:newspaper: 报纸等纸质读物。而且主题以一种:light_bulb:极其巧妙的方式实现了当下(2019)流行的:last_...
### IntelliJ IDEA 文件持续闪烁与Updating and Indexing问题详解 #### 一、问题概述 在使用IntelliJ IDEA进行开发过程中,部分用户可能会遇到一个较为常见的现象:IDE中的文件图标会不断闪烁,同时状态栏提示...
Java.util.ConcurrentModificationException 异常问题详解 ConcurrentModificationException 异常是 Java 中一个常见的异常,它发生在 Iterator 遍历集合时,集合同时被修改引起的异常。在 Java 中,集合类如 ...
cmpr 软件的更新软件,一般浏览器网页下载不下来。 cmpr_updating
Unity的更新系统!
PART II Querying and Updating Data . . . . . . . . . . . . . . . . 71 CHAPTER 5 SELECT Statement: Common Elements . . . . . . . . . . . . 73 5.1 Introduction . . . . . . . . . . . . . . . . . . . . . ...
在Centos上部署项目发现一个奇怪的问题,数据库连接一直抛异常。于是花了两个小时搜了各种数据库连接异常导致的原因,最终问题得以解决。同时,把解决过程中搜集到的异常信息汇总一下,当大家遇到类似的问题时,给...
14.4 Updating......275 14.5 Closing Thoughts..... . . 276 V Appendixes 277 A Java vs. the Android Language and APIs 278 A.1 Language Subset..... . . 278 A.2 Standard Library Subset.... . . 280 A...
APIS (keep updating...) 权限相关 [Demo] ActivityExt [Demo] AppExt AesExt [Demo] CommonExt Constants DrawableExt FileExt HashExt [Demo] IntentExt [Demo] KtxManager [Demo] KtxSpan [Demo] ...
Jeecgboot(PostgreSQL)集成指南 Jeecgboot 是一个基于 Spring Boot 的低代码开发平台,旨在帮助开发者快速构建企业级应用程序。PostgreSQL 是一个功能强大且免费的开源关系数据库管理系统。本文将指导您如何将 ...
chromium的depot_tools,windows版本,如果你被墙挡住了,可能需要它。这是我用国外的云服务器下载回来的,更新日期2016年10月28日。 需要macos版本的请搜索我的另一个资源chromium depot_tools for macos。
Everything search engine Small installation file Clean and simple user interface Quick file indexing Quick searching Minimal resource usage Share files with others easily Real-time updating More...
% APSM-jSO: A novel jSO variant with an adaptive parameter selection mechanism and a new external archive updating mechanism. % Swarm and Evolutionary Computation, ...
crates.io-index:crates.io的注册表索引